/* qCore.js (qJSLib)
 
  @Summary  : Core Library for qJSLib
  @Author   : Timothy C. Quinn
  @License  : http://www.opensource.org/licenses/mit-license.php
  
  @Todo:
   - Fix issue with error popup window in IE - The width is to much on errors because of long uri
   - Debugger:
   -- If a raw error is thrown down the stack (not qErr), the error is sometimes ignored
   --- Maybe create a qErrClear() that clears the error stack
   --- -or- maybe create timestamp on qErr and detect in Master Handler. If error is stale, ignore it.
   -- Figure out how to handle multiple errors
   --- Eg. Multiple async Ajax Calls that all return errors
   
  @Notes:
   - Some logic may need core code and API re-write to remove license unfriendly elements
*/

// Globals
_w=window; _d=document; _wo=_w.opener

/* MOZ/IE CLIENT SNIFFER (is.ie5.5+ && !is.ie 5+ && is.wk (?)) */
function ClientSniffer(){
    var t=this, n=navigator,sUA=n.userAgent.toLowerCase(),i; 
//alert(sUA)
//alert(n.appVersion)
    t.ie=false;
    t.moz=false; 
    t.wk=false; 
    
    var M= sUA.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
    if(M && (tem= sUA.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
    M= M? [M[1], M[2]]: [N, n.appVersion, '-?'];
    t.browser=M[0]
    t.ver=M[1]
    t.verMajor=parseInt(t.ver)
    if((i=sUA.indexOf('msie'))>-1&&parseFloat(sUA.substring(i+5,sUA.length))>=5.5){
        t.ie=true
    }else{
        if(sUA.indexOf('gecko/')!=-1&&parseInt(n.appVersion)>=5){
            t.moz=true
            i = sUA.indexOf("; rv:")
        } else {
            if(sUA.indexOf('applewebkit/')!=-1){
                t.wk=true
            }
        }
    }; 
}; 
_w.is=new ClientSniffer()

_SP=String.prototype;
_AP=Array.prototype; 

/* Boolean Functions */
function isArray(a){ return (isUndef(a) ? false : ( (isFunc(a.join)&&isFunc(a.slice)&&isDef(a.length)) )) }
function isObj(o){var s=oGetClassOf(o); return (s&&s!="String")?true:false}; function isObject(o){return isObj(o)}
function isNum(i){try {if(i===undefined||i===true||i===false||(i.trim&&i.trim()==="")){return false;};return !isNaN(i); }catch(x){ return false }}
function isElem(s){return (s$(s).indexOf("[object")>-1)?true:false}
function isDD(o){return (o&&(o.type=="select-one"||o.type=="select-multiple"))?true:false}
function isUndef(o){return (o===undefined||o===null||isJNull(o))?true:false}
function isDef(o){return !isUndef(o)}
function isError(o){var v;if(is.ie){return (o&&(v=o.constructor)&&(v=v.prototype)&&s$(v).toLowerCase()=="[object error]")?true:false} else {return oGetClassOf(o).indexOf("Error")>-1?true:false}}; isErr=isError;
function isFunc(o){ return (o && o.call && o.apply)?true:false }
function isStr(s){return (typeof(s)=="string")}
function isBool(s){return (isUndef(s))?false:(typeof(s)=="boolean")?true:(isNum(s)||!isStr(s))?false:(["true","false"].has(s.toLowerCase())?true:false)}
function isNVArray(a){ return (!isArray(a)||a.length%2>0)?false:true }
function isInt(i){ var p=parseInt(i);return (isNaN(p)||p!=i)?false:true }
function isJson(o){return oGetClassOf(o)== "Object"?true:false }
function isEvent(o){return (o&&(o.isPseudoEvent||(is.ie&&o.srcElement)||(o.target)))?true:false}
function isJNull(o){return o&&o.JNULL?true:false}
/* end Booleans */

function JNull(){return {JNULL:true, toString:function(){return "(JNull)"}} }

/* Function Parsing */
function funcName(func){ var p=/function\s+(\w+)/.exec(func+""); return p?p[1]:null }
function funcArgs(func){ var p=/function[^(]*\(([^)]*)\)/.exec(func+""); if(p&&p[1]){ p[1]=p[1].replace(/\s/g,""); return p[1].split(",") } else return null }

/* DEBUG */

function qCoreErr(s, e, j){
    if(isError(s)){j=e;e=s;s=""}
//alert(
//     "!!qCoreErr!!"
//    +("\n s = `"+q$.dump(s)+"`")
//    +("\n e (dump) = `"+(isDef(e)?q$.dump(e):"null")+"`")
//    +("\n e.message = `"+(isDef(e)?e.message:"(noerr)")+"`")
//    +("\n j = `"+q$.dump(j)+"`")
//    +("\n isError(s) = `"+isError(s)+"`")
//    +(is.ie?"":"\nCALL STACK:\n`"+s$.pad((new Error).stack+"`"))
//	  +("\n args:\n"+s$.pad(q$.dumpArgs()))
//)

    var t=this,aSTE,aF1,aF2,sR="";
    try {

        aSTE=getStackTrace(e, true)

        aF1=aSTE[aSTE.length-1]
        aF2=aSTE[aSTE.length-2]
        if(e)e.__isQCoreErr=true

        __q(".: qCore Error :.\n\nmsg:\n"+s+(e?"\n"+e.message:""))
        __q("Full Stack", q$.compileStack(aSTE))
        __q("\nFrom : "+q$.compileStack([aF1]))
        __q("Caller: "+q$.compileStack([aF2]))
        
        if(j)__q("Info", q$.dump(j))
        sR+="\n\n.:end:."
        pc(sR);alert(sR);
        if(e)e._qcmsg=sR
    }catch(x){alert("!!!qCoreErr failed!!!"+x.dump());throw x}
  
    throw e
    function __q(k,v){sR+=isDef(v)?("\n\n.: "+k+" :.\n"+s$.pad(v)):"\n"+(k)}
}

stFunc=0;stArgs=1;stVals=2;stFile=3;stPath=4;stLine=5
q$ = {
    
   // debugDump Json Params
     ARG_MSG            : "msg"         // <~ (Str)
    ,ARG_ERR            : "err"         // <~ (Error)
    ,ARG_TRACES         : "traces"      // <~ (Str[])
    ,ARG_VAR_DUMP       : "varDump"     // <~ (json) of vars dumped
    ,ARG_MSG_EXTRA      : "extraMsg"    // <~ (Str)
    ,ARG_MSG_EXTRA_TOP  : "extraMsgTop" // <~ (Str)
    ,TO_STR_TITLE       : ".: qDebug Dump :."
    ,NULL               : "(null)"
    ,NULLDATE           : "(nulldate)"
    ,SDF_dateTime_CS    : "MM/dd/yyyy HH:mm:ss"
    ,SDF_dateOnly_CS    : "MM/dd/yyyy"
    ,SDF_dateTime       : "MMM d, yyyy h:mm a"
    ,SDF_dateOnly       : "MMM d, yyyy"
    ,ERROR_CLASS: "ERROR_CLASS"
    
    ,MK_fieldKeys: "fieldKeys"
    ,MK_jsParent: "jsParent"// <~ Parent JS Object - Using this key will prevent recursion in dump logic
    
    ,getTS: function q$_getgetTS(){return (new Date()).getTime()}


    ,dumpVarDump: function q$_dumpVarDump(jVarDump){
        var sRet=""
        if(isDef(jVarDump))
            sRet+=q$.dump(jVarDump)
        return sRet
    }
    
    ,dumpTraces: function q$_dumpTraces(aTraces){
        var sRet="", bFirst=true
        for(var i=0;i<aTraces.length;i++){
            if(isDef(aTraces[i]) && aTraces[i].trim()!=""){
                sRet+=(bFirst?"":"\n")+"  ~> "+aTraces[i].trim();bFirst=false
            }
        }
        return sRet
    }
    ,dump: function qdbg_dump(o, bShowType){
		var s
        try {
            if(isStr(o)||isNum(o)||isBool(o)){
                return (!bShowType?"":isStr(o)?"(str) ":isBool(o)?"(bool) ":"(num) ")+s$(o)
            }else if(isArray(o)) {
                return (!bShowType?"":"(array) ")+q$.dumpArr(o)   
            } else if(isJson(o)) {
            	s=q$.dumpJson(o)
                return (!bShowType?"":"(json) ")+(s===""?"{}":s)
            } else {
                return isUndef(o)?"(undef)":" ("+oGetClassOf(o)+") "+(o.toString?o.toString():o)
            }
        }catch(x){
//alert(
//    "!!dump error!!"
//   +"\n o = `"+o+"`"
//   +"\n o is null = `"+(o == null)+"`"
//   +"\n isStr(o) = `"+(isStr(o))+"`"
//   +"\n isNum(o) = `"+(isNum(o))+"`"
//)
            qCoreErr("!!!qdbg_dump failed!!!",x)}
    }
    ,dumpObj: function qdbg_dumpObj(o){
        return o?"("+(typeof o)+")"+this.dump(o):"(null)"
    }
    ,dumpNVArr: function qdbg_dumpNVArr(nv){ var s=""; for(var i=0;i<nv.length;i++){ if(i>0){s+="\n"}; s+=nv[i++]+" - "+nv[i]}; return s }
    
    
    ,_DJRT: null
    ,_dumpRG: function qdbg__dumpRG(o){
    	var t=this,sCFN=funcName(arguments.callee.caller.caller),aRc
    	if(!(sCFN==="qdbg_dumpJson") && !(sCFN==="qdbg_dumpArr")){
    		t._DJRT=[o]
    	}else{
    		if(o==(aRc=t._DJRT)[aRc.length-1]){
    			return true
    		};
    		aRc.p(o)
    		return false
    	}
    }
    ,dumpArr: function qdbg_dumpArr(o){
        var t=this,sR="", r
        if(t._dumpRG(o)){return "(recursion blocked)";}
        for(var i=0;i<o.length;i++){r = o[i]
            if(i>0)sR+=" | "
            if(isUndef(r)){
                sR+="(null)"
            } else if(isStr(r)||isNum(r)){
                
                sR+=r
            }else if(isArray(r))
                sR+=(i==0?"":"\n")+"["+i+"]"+q$.dumpArr(r).pad()
            else if(isJson(r))
                sR+=" ("+oGetClassOf(r)+"):\n"+q$.dumpJson(r).pad()
            else
                sR+=" ("+oGetClassOf(r)+") "+r.toString()
        }
        return sR
    }
    ,dumpJson: function qdbg_dumpJson(o,bNoSort){
        var t=this,aP=qObjListProps(o,!bNoSort), sb=new StringBuffer(), oV,oK,sV,sCN
		if(t._dumpRG(o)){return "(recursion blocked)";}
        for(var i=0;i<aP.length;i++){oK=aP[i]; oV=o[oK]; sCN=""
        	
//pc("oK = "+oK+", Name = "+o.Name)
        	
            if(i>0)sb.a("\n")
            if(oK === q$.MK_jsParent){
            	sV="(value is JS Parent. Skipping dump to prevent recursion)"
            }else if(isStr(oV)){
                sV=s$(oV)
            }else if(isNum(oV)){
            	sCN="num"
                sV=s$(oV) 
            }else if(isBool(oV)){
            	sCN="bool"
                sV=s$(oV)
            }else if(isArray(oV)){
            	sCN="array"
            	sV=q$.dumpArr(oV);
            }else if(isJson(oV)){
            	sCN="json"
            	sV=q$.dumpJson(oV);
            }else if(isUndef(oV)){
                sV="(undef)"
            }else {
            	sCN=oGetClassOf(oV)
            	sV=s$(oV)
            }
            sCN=sCN?" ("+sCN+")":""
            sb.a(oK)
            if(sV.indexOf("\n")>0 || sV.length>60){
            	sb.a(sCN).a(":\n").a(sV.pad())
            } else {
            	sb.a(sCN).a(" = ").a(sV)
            }
        }
        return sb.ts()
    }

    ,dumpSte: function qdbg_dumpSte(ste){ return this.compileStack([ste]) }
    ,dumpArgs: function qdbg_dumpArgs(){ 
        var s="",a=qArgToArray(arguments.callee.caller.arguments);
        for(var i=0;i<a.length;i++){s+=(i==0?"":"\n")+"[arg "+i+"]:\n"+s$.pad(q$.dump(a[i]),". ")}; 
        return s
    }
    ,compileStack: function qdbg_compileStack(a){
        var s="",aT,r;
        if(!a)return "(null) - called from: "+funcName(arguments.callee.caller)+"()"
        for(var i=0;i<a.length;i++){
            try{
    //pc("a = `"+a+"`",true)
                if(isUndef(a[i]))
                    s+="a at `"+i+"` is = `"+a[i]+"`"
                else{
                    s+=(i>0?"\n":"")+(a.length==1?"":"  "+(i+1)+" - ")+(a[i][stFunc]==""?"~()":a[i][stFunc]+"()")+((a.length>1&&is.ie&&i==0)?"*":"")
                    if(!is.ie){ s+="(" +(a[i][stFile]||"(chrome)")+":"+a[i][stLine]+")" };

                }
            }catch(x){ qErr("a = `"+q$.dump(a)+"`", x) }
        };
        return s+((a.length>1&&is.ie)?"\n  IE RC == || != *":"")
    }
    ,getThrowStackInfo :function qdbg_getThrowStackInfo(e,bVerb){
        var bApp, sRet="",aDD, dd, stack,s;
//pc(
//    "!!!getThrowStackInfo!!!"
//   +"\n w = "+e
//   +"\n bVerb = "+bVerb
//   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)
        try {
            aDD = e.__throwStack||[];
            for(var i=0;i<aDD.length;i++){dd=aDD[i];
//pc("aDD "+i+" "+aDD[i])
                s = dd.toString(QOpt({prefOrd : [dd.MESSAGE, dd.TRACES, dd.VARS]}))
                if(s!=".: message :.\n  (no msg)"){
                    stack = dd.getSect(dd.STACK_ARRAY)
                    sRet+=(i==0?"":"\n")+"[ "+q$.dumpSte(stack[0])+" ]\n";
                    sRet+=s$.pad(dd.toString(QOpt({prefOrd : [dd.MESSAGE, dd.TRACES, dd.VARS], verbose: bVerb})))
                }
            }
            return sRet.toString().replace(/\n:  .  /g, "");
        }catch(e2){qCoreErr("getThrowStackInfo Core Error",e2,{varDump:{args: q$.dumpArgs()}})}
    }
    
    ,_ErrorLog :[]
    ,_LastErr  :null
    ,MK_errorHandled: "errorHandled"
    ,tohandle_MozMastErr: null
    ,mozMastErr_to: function qdb_mozMastErr_to(){
    	var t=this
    	if(t._LastErr&&!t._LastErr[t.MK_errorHandled]){
    		Window_error()	
    	}
    }
    ,clearLastError : function qdbg_clearLastError(bHandled){
        var t=this
        if(!t._LastErr)return
        if(bHandled)t._LastErr[q$.MK_errorHandled]=true
        t._ErrorLog.p(t._LastErr)
        t._LastErr=null
    }
    
    ,parseErr: function qdbg_parseErr(e){
        if(!e.__isQErr){
            e.__isQErr=true;
            e.__throwStack=[];
            a=getStackTrace(e, true);
            e.priv_stack=a
        }	
    }
	

    ,parseDbgArgs : function  qdbg_parseDbgArgs(a){
//pc(
//    " CALLED "
//   +"\n a:\n"+s$.pad(q$.dump(a),". ")
//)
        var j={},msg,err,jdbg
      // Parse Args
        if(a.length==1){
            v=a[0]
            if(isError(v))
                j.err=v;
            else if(isQDD(v))
                j.dd=v;
            else 
                j.msg=isStr(v)?v:"("+oGetClassOf(v)+")\n"+q$.dump(v)
        } else if (a.length==2){
            v=a[0]
//pc(
//    " isError(v) = "+isError(v)
//   +"\n v:\n"+s$.pad(q$.dump(v),". ")
//   +"\n stack:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)
            if(isStr(v))j.msg=v;
            else if(isError(v)) j.err=v;
            else __iam(a, 2);
            v=a[1]
            if(isDef(v)){                
                if(isError(v))j.err=v;
                else if(isJson(v))j.jdbg=v;
                else __iam(a, 3);
            }
        } else if(a.length==3){
            if(!isStr(v=a[0]))__iam(a, 4);j.msg=v;
//alert("TEST: `"+isError(a[1])+"`, a[1] = `"+a[1]+"`, "+a[1].message)
            v=a[1];if(isDef(v)&&!isError(v))__iam(a, 5);j.err=v;
            v=a[2];if(isDef(v)&&!isJson(v))__iam(a, 6);j.jdbg=v;
        } else
            __iam(a, "Too Many Arguments!");
            
//pc(
//    " j.msg = "+j.msg
//   +"\n j.err = "+j.err
//   +"\n j.jdbg:\n"+s$.pad(q$.dump(j.jdbg))
//   +"\n stack:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)
            
        if(isUndef(j.jdbg))j.jdbg={}

//alert("!! j.err = "+j.err+"\n\nStack: "+(new Error()).stack)

        return j
        
        function __iam(a, iErrNo){
            try {
                var v, aArgs=qArgToArray(a),sRet="debugDump() - Invalid Args Passed. Expecting one of ([String], [Error], [String, Error], [String, json], [Error, json], [String, Error, json])"
                if(isDef(iErrNo))sRet+="\nErrNo: "+iErrNo
                sRet+="\nArguments:"
                for(var i=0;i<aArgs.length;i++)sRet+="\nARG["+i+"]:"+s$.pad(" |"+q$.dumpObj(aArgs[i]).replace(/\n/g, " ~| ")+"|")
            }catch(xx){alert("internal __iam error: "+xx); throw xx}
            pc(debugDump(sRet))
            qCoreErr("parseDbgArgs Core Error", new Error(sRet),{varDump:{args: q$.dumpArgs()}})
        }
           
    }
    
    ,getCallerInfo : function qdbg_getCallerInfo(iForceLevel){
        if(arguments.length==0){iForceLevel=2}else{if(iForceLevel<1)iForceLevel=1}
        var aStack=getStackTrace(new Error(),true, {showAll: false}),r=aStack[iForceLevel]
//pc(
//     "\n r = "+r
//    +"\n iForceLevel = "+iForceLevel
//    +"\n aStack:\n"+s$.pad(aStack.join("\n"))
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
        if(!r)r=aStack[iForceLevel-1]
        if(!r)r=aStack[iForceLevel-2]
        if(!r)qErr("Could not resolve Stack at level "+iForceLevel)
        if(is.ie){return r[stFunc]}
        return r[stFunc]+"() - "+r[stFile]+" - "+r[stLine]
    }
}




// StackTraceElementRec
function isQErr(o){
    return (isDef(o)&&o.__isQErr)?true:false
}
function qErr(){
//    pc("CALLED")
    var a=arguments,e,v,dd,j,msg,jarg,e2,bFirst
    j=q$.parseDbgArgs(a)
    
    if(!is.ie){// This timeout is designed to handle https://bugzilla.mozilla.org/show_bug.cgi?id=312448 
    	q$.tohandle_MozMastErr=setTimeout("q$.mozMastErr_to()", 250)
	}
//	pc(
//	    "!!!qErr!!!"
//	   +"\n isError(j.err) = "+isError(j.err)
//	   +"\n ARGS:\n"+s$.pad(q$.dumpArgs())
//	   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//	)
	
//alert(
//	"!!!qErr!!!"
//   +"\n Stack = "+getStackTrace()
//   +"\n args = "+q$.dumpArgs()
//   +"\n j:\n"+s$.pad(q$.dumpJson(j))
//)
    msg=isDef(v=j.msg)?v:""
    if(!isError(e=j.err)){
        e=new Error(msg)
        dd=debugDump(e,j.jdbg)
//debug(
//	"!!!qErr!!!"
//   +"\n msg = "+msg
//   +"\n dd = "+dd
//   +"\n"
//)
        
//pc(
//    "!!!qErr!!!"
//   +"\n ARGS:\n"+s$.pad(q$.dumpArgs())
//   +"\n j:\n"+s$.pad(q$.dump(j))
//   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)
        
    } else {// Subsequent Catch Call
        e2 = new Error(isDef(v=j.msg)?v:"(no msg)")
        dd=debugDump(e2,j.jdbg)
    }   
//pc(
//    "\n dd:\n"+s$.pad(q$.dump(dd))
//)

	q$.parseErr(e)
    e.__throwStack.p(dd)
        
    if(e!=q$._LastErr){
        q$.clearLastError()
        q$._LastErr=e
    }

    throw e

}

/* Debug Dumper (private) */
qDD = function qDebugDump(){this.priv_constr(arguments);}
_QDDP=qDD.prototype
// Constants
// . Sections
_QDDP.MESSAGE      = "message"
_QDDP.INFO         = "info"
_QDDP.STACK        = "stack"
_QDDP.STACK_ARRAY  = "stack array"
_QDDP.TRACES       = "traces"
_QDDP.VARS         = "vars"
_QDDP.INNER_DEBUG  = "inner debug"
_QDDP.QCLIENT_INFO = "qclient info"
_QDDP.END          = "end"
// . Options
_QDDP.OP_TERS      = "terse"
_QDDP.OP_VERB      = "verbose"
_QDDP.OP_PREF_ORD  = "prefOrd"
_QDDP.OP_SECT_TYPE = "sectType"
_QDDP.OP_SPACE_SECT = "spaceSection"
_QDDP.SECT_TYPE_STD = "standard"
_QDDP.SECT_TYPE_ALERT = "alert"
_QDDP.nvSect   = [_QDDP.INFO, _QDDP.VARS]
_QDDP[_QDDP.OP_PREF_ORD]  = [_QDDP.MESSAGE, _QDDP.STACK, _QDDP.TRACES, _QDDP.VARS, _QDDP.QCLIENT_INFO, _QDDP.INFO, _QDDP.INNER_DEBUG]
// . Other Info
_QDDP.OI_ERROR_ID   = "error id"
_QDDP.OI_ERROR_CLS  = "error class"
_QDDP.OI_CALLER     = "caller"
_QDDP.OI_TIMESTAMP  = "timestamp"
// . Special Chars
_QDDP.BLK_START=".: "
_QDDP.BLK_END=" :."
// . Static Settings
_QDDP.TERSE_CROP = 2
_QDDP.REG_CROP = 5
// Constructor
_QDDP.priv_constr = function qdd_priv_constr(args){
    var t=this,d=new Date()
  // Init Working Props
    t.__isQDD=true
    t.jDat = {}
    t.rootCause=null
    t.append(t.INFO, [t.OI_TIMESTAMP, d.getFullYear()+"-"+d.getMonth()+"-"+d.getDate()+" "+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()])//.(new QDate()).format("yyyy-MM-dd HH:mm:ss")])
    t.append(t.INFO, [t.OI_ERROR_ID, nRand(5)])
}
function isQDD(o){return (o&&o.__isQDD)?true:false}

// General Methods
_QDDP.toString =function qdd_toString(qOpt){
    var t=this,d=t.jDat,aPO=t.prefOrd,sR="",v,bUseStd,bSpaceSect
    
//pc(
//    "!!!qdd_toString!!!"
//   +"\n qOpt:\n"+s$.pad(q$.dumpObj(qOpt))
//   +"\n stack:\n"+s$.pad(q$.dump((new Error()).stack))
//   +"\n\n"
//)
    
    if(isQOpt(qOpt)){// Opts
        aPO=((v=qOpt[t.OP_PREF_ORD])&&isArray(v))?v:aPO
        bSpaceSect=qOpt[t.OP_SPACE_SECT]?true:false
    }

    for(var i=0;i<aPO.length;i++){
//pc(
//     "\n aPO[i] = "+aPO[i]
//    +"\n i = "+i
//    +"\n t.dumpSect(aPO[i],qOpt) = "+t.dumpSect(aPO[i],qOpt)
//);
        if((v=t.dumpSect(aPO[i],qOpt))!=""){
            if(bSpaceSect&&sR!="")sR+="\n";sR+=(i==0?"":"\n")+v
        }
    }
    return sR
}


_QDDP.dumpSect =function qdd_dumpSect(s, qOpt){
    var t=this,args=arguments,bTers=false,bVerb=false,bReg=true, o=t.jDat[s], bUseStd=true,v, sR="",iCrop,r,bSecIsNV,o2;
    bSecIsNV=t.nvSect.has(s)
    
    if(s==t.STACK||s==t.STACK_ARRAY){// Get Stacks from Root Cause Only
        var errRC,aST
        if( !(errRC=t.rootCause) ){
//        	pc("WARNING - Error has no Root Cause!\n stack:\n"+s$.pad(getStackTrace()))
        	return "(no root cause!)"
        } else {
            aST=errRC.priv_stack
//pc(
//     "\n t.rootCause = "+t.rootCause
//    +"\n aST = "+aST
//    +"\n q$.compileStack(aST) = "+q$.compileStack(aST)
//    +"\n aST = "+aST
//    +"\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
            if(s==t.STACK){return q$.compileStack(aST)} else {return aST}
        }
    }
    o=o2||t.jDat[s]
    if(isUndef(o)||isStr(o)&&o.trim()==""){return "";}
    
    if(isQOpt(qOpt)){
        bTers=qOpt[t.OP_TERS]?true:false;
        bVerb=qOpt[t.OP_VERB]?true:false;
        bReg=(!bTers&&!bVerb);
        bUseStd=((v=qOpt[t.OP_SECT_TYPE])&&v==t.SECT_TYPE_ALERT)?false:true;
    }


    iCrop=bVerb?9999:bTers?t.TERSE_CROP:t.REG_CROP;

//pc(
//    "!!!qdd_dumpSect!!!"
//   +"\n s = "+s
//   +"\n bTers = "+bTers
//   +"\n bVerb = "+bVerb
//   +"\n bReg = "+bReg
//   +"\n bUseStd = "+bUseStd
//   +"\n iCrop = "+iCrop
//   +"\n qOpt:\n"+s$.pad(q$.dumpObj(qOpt))
//   +"\n stack:\n"+s$.pad(q$.dump((new Error()).stack))
//   +"\n\n"
//)
    sR+=(bUseStd?(t.BLK_START+s+t.BLK_END):(s.toUpperCase()+": "));
    if(!bSecIsNV){
        v=o
//pc(
//    "\n\n"
//   +"\n o:\n"+s$.pad(o)
//   +"\n\n"
//)
    } else {
        var v2,v=""
        for(var i=0;i<o.length;i++){r=o[i]
            try {
                v2=t.crop(q$.dump(r[1]), iCrop)
//pc(
//    "\n\n"
//   +"\n v2:\n"+s$.pad(v2)
//   +"\n\n"
//)
                v+=(i==0?"":"\n")+r[0]+": "+(v2.indexOf("\n")>-1?"\n"+s$.pad(v2):v2)
            }catch(xx){alert("!_QDDP.dumpSect Error! r[0] = `"+r[0]+"`, r[1] = `"+r[1]+"`")}
        } 
    }
    return sR+(bSecIsNV||s$(v).indexOf("\n")>-1||s==t.MESSAGE?"\n"+s$.pad(v):v)
}
_QDDP.crop =function qdd_crop(s, iCrop){
	var aV=s$(s).split("\n"); if(iCrop>aV.length)return s; var aV2=aV.splice(0,iCrop-1); return aV2.join("\n")+" (...)"
}
_QDDP.getSect =function qdd_getSect(s){
    var t=this,v=t.jDat[s]
    if(isUndef(v)){qCoreErr("Invalid Section: `"+s+"`"), new Error(),{varDump:{args: q$.dumpArgs()}}}
    return v
}
_QDDP.setSect =function qdd_append(s, oV){
    var t=this; t.priv_initSect(s)
    t.jDat[s]=oV;
}
/* Appends to section or Appends to block within section */
_QDDP.append =function qdd_append(s, oV){
    var t=this; t.priv_initSect(s), o=t.jDat[s];
    if(t.nvSect.has(s)){
        if(!isArray(oV)||oV.length!=2){return qCoreErr("oV Must Be array[2].", new Error(),{varDump:{args: q$.dumpArgs()}})}else{o.p(oV);};
    } else {
        t.jDat[s]=(s$(o).trim()==""?"":o+"\n")+oV   
    }
}
/* Not used. Good naming though... */
_QDDP.prepend =function qdd_prepend(s, sV){
    var t=this,o;
    t.priv_initSect(s); o=t.jDat[s]; 
    if(t.nvSect.has(s))qCoreErr("sV must only be for String sections", new Error(),{varDump:{args: q$.dumpArgs()}});
    t.jDat[s]=sV+o
}
_QDDP.priv_initSect =function qdd_priv_initSect(s){
    var t=this,d=t.jDat; if(isDef(d[s]))return; d[s]=(t.nvSect.has(s)?[]:"")
}
/* end Debug Dumper */

__qSkipStack=["qErr","_MOZ_getStackTrace","_IE_getStackTrace","getStackTrace","debug","debugErr","getDebugMsg", "debugDump","Error","Window_error"]

// Returns StackTraceElementRec
function getStackTrace(e, bArray, j){try{
/*
    @TODO:
    - Analyse why caller crawl does not work with base() calls
*/
    var args=arguments,iA=args.length,c=args.callee.caller,aCS=[],iL,sF,sR,sP,iF,oH,aR=[],iELB=0,sStack,cLast,iRecCtr=1,bShowAll;j=j?j:{}
    bShowAll=iA<3?_w.bDebug:j.showAll

  // Parse Callee.Caller stack
    while(c!=null){
        cLast=c;
        sF=s$(funcName(c))
        if( bShowAll || !__qSkipStack.has(sF) ){
            aCS.p([sF,funcArgs(c),c.arguments])
        };
        try {
            c=c.caller
        }catch(exc2){
            if(s$(exc2).indexOf("Permission denied")>-1)break;
        }
        if(s$(c)==s$(cLast)){
          // Detect if stack has call to base()
            if(s$(c).indexOf(".base()")>-1){
//                pc("!!!BASE() call Detected. Stopping caller crawl "+iRecCtr+"!!!\n caller: "+[sF,funcArgs(c),c.arguments])   
                aCS.p([sF+" (BASE() call detected. Stopping caller crawl)",funcArgs(c),c.arguments])
                break
            } else {
                iRecCtr++    
                if(iRecCtr>30){
//                    aCS.p([sF+" (Recursion blocked at 30)",funcArgs(c),c.arguments])
                    break;   
                }
            }
        } else {
            iRecCtr=1

            iELB++; if(iELB>100){
                if(sF.indexOf("base_constr")==-1){
                    sMsg = "getStackTrace - Endless Loop Trapped at "+iELB+": "+sF+"\n"
                       +(!is.ie?((new Error("")).stack):"")
                       +("Current Stack Captured:\n")+s$.pad(aCS.join("\n"))
                    pc(sMsg)
//                    alert(sMsg)
                };
                break 
            }
        }
    }

    if(aCS.length==0){aCS.p(["chrome/window","",""])}
    if(is.ie){
        aR=aCS
    } else {// !is.ie
        if(!isError(e)){e = new Error()}
        aR=is.moz?parseMozStack(e, false):parseWkStack(e, false)
      // Overlay Call Stack Args/Vals
        for(var i=0;i<aR.length;i++){aRow=aR[i];
            sF=aRow[stFunc]
            if(sF!=""){
                iR=-1; for(var j=0;j<aCS.length;j++){ if(sF==aCS[j][0]){iR=j;break} } // Get Match
                if(iR!=-1){
                    aRow[stArgs]= aCS[iR][stArgs]
                    aRow[stVals]= aCS[iR][stVals]
                }
            } 
        }
    }

}catch(x){
    if(_w._DisableAllErrors){throw x;}
    var w=_w.open("","_blank"); 
    w.document.write(("getStackTrace Failed:\nMsg: "+x.message+"\n\nstack:\n"+(!is.ie?x.stack:aS)).replace(/\n/g,"<br>").replace(/ /g,"&nbsp;"))
    _w._DisableAllErrors=true; throw x
};
    if(bArray&&!is.ie)aR.z_rawStack=sStack
    return bArray?aR:q$.compileStack(aR)
}

function debug(s,e) {
    pc("CALLED")
    var sErr,s,sCaller,dd
    try {
    	if(isError(s)){e=s;s=""};s=s$(s)
//pc(
//     "!!debug!!"
//    +"\n s = "+s
//    +"\n e = "+e
//    +"\n isDef(e) = "+isDef(e)
//);
    	
	    sCaller=q$.getCallerInfo(1)
		
	    dd=isDef(e)?debugDump(s,e):debugDump(s)
//pc(
//     "\n dd.getSect(dd.STACK_ARRAY) = "+dd.getSect(dd.STACK_ARRAY)
//    +"\n dd.getSect(dd.STACK) = "+dd.getSect(dd.STACK)
//    +"\n dd.toString() = "+dd.toString()
//);
	    if(isQDD(dd)){
	        dd.append(dd.MESSAGE, "\nCaller: "+sCaller)
	        sErr = dd.toString(QOpt({sectType: "alert", spaceSection: true}))
	    }else{
	        sErr=dd+"\nCaller="+sCaller
	    }
	    sErr+="\nEND"
	    alert(!is.ie?sErr.replace(/ /g,"\xA0"):sErr)
	}catch(x){qCoreErr(x)}
    return sErr
}
function debugErr(s,e) {
    var sErr
    if(isError(s)){e=s;s=""};s=s$(s)
//pc(
//     "!!debugErr!!"
//    +"\n s = "+s
//    +"\n e = "+e
//    +"\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
    sErr=debug(s,e)

//alert("!debugErr! "+(e.message)+"|"+sErr+"|"+(isError(e))+"|"+(isQErr(e)))
    if(isError(e))throw e
    if(s==""){qErr(e)}else{qErr(s,e)}
}

// Signatures: [String], [Error], [String, Error], [String, qOpt], [Error, qOpt], [String, Error, qOpt]
function debugDump() {
//    pc("CALLED")
    var sMsg, sR,stack, msg, exc, aSTE, args=arguments,v, jDebugData, err,j,iCSA

    try {
    
        j=q$.parseDbgArgs(args)
        
//pc(
//    "!!!debugDump!!!"
//   +"\n isError(j.err) = "+isError(j.err)
//   +"\n isJson(j.jdbg) = "+isJson(j.jdbg)
//   +"\n ARGS:\n"+s$.pad(q$.dumpArgs())
//   +"\n j:\n"+s$.pad(q$.dump(j))
//   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)

        if(isError(j.err)){

            var sMsg,dd=new qDD(), trc, vars, msgExtr, mxgExtrTop
            
            q$.parseErr(j.err)
            
            dd.rootCause=j.err
            
            if(isJson(j.jdbg)){
                try {
                    trc         = agetParam_arr ("jDebugData", j.jdbg, q$.ARG_TRACES, false)
                    vars        = agetParam_obj ("jDebugData", j.jdbg, q$.ARG_VAR_DUMP, false)
                    msgExtr     = agetParam     ("jDebugData", j.jdbg, q$.ARG_MSG_EXTRA, false)
                    mxgExtrTop  = agetParam     ("jDebugData", j.jdbg, q$.ARG_MSG_EXTRA_TOP, false)
                    bVerb       = agetParam_bool     ("jDebugData", j.jdbg, "verbose", false)
//pc(
//    "\n trc:\n"+s$.pad(q$.dump(trc))
//   +"\n vars:\n"+s$.pad(q$.dump(vars))
//   +"\n msgExtr:\n"+s$.pad(q$.dump(msgExtr))
//   +"\n mxgExtrTop:\n"+s$.pad(q$.dump(mxgExtrTop))
//   +"\n bVerb:\n"+s$.pad(q$.dump(bVerb))
//)
                }catch(x){
                    qCoreErr("debugDump CORE Error", x)
                }
            }

            sMsg=""
            if(isDef(v=mxgExtrTop)&&v.trim()!="")sMsg+=v+"\n"

            if(isDef(v=j.err.message)&&s$(v).trim()!=""){sMsg+=v+"\n"}

            if(isDef(v=j.msg)&&v.trim()!=""){sMsg+=v+"\n"}
            if(isDef(v=msgExtr)&&v.trim()!=""){sMsg+=v+"\n"}

            if(sMsg!="")sMsg=sMsg.substring(0,sMsg.length-1)
            dd.append(dd.MESSAGE, sMsg)
            stack = j.err.priv_stack||getStackTrace(j.err, true)
            
//pc(
//    "!!!debugDump!!! Raw"
//   +"\n stack:\n"+s$.pad(stack)
//   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)
            
//            if(isDef(iCSA=j.jdbg.cropStackAt)){
//                stack = stack.splice(iCSA, 999)
//            }
//pc(
//    "!!!debugDump!!! After Clean"
//   +"\n stack:\n"+s$.pad(stack)
//   +"\n isDef(v=stack) = "+isDef(v=stack)
//   +"\n CALL STACK:\n"+s$.pad(q$.dump((new Error).stack),". ")
//)

            if(isDef(v=stack)){
                dd.setSect(dd.STACK_ARRAY, v)
                dd.append(dd.STACK, q$.compileStack(v))
            }
            if(isDef(v=vars)){
                var aNV=isJson(v)?qObjGet(v):v
                for(var i=0;i<aNV.length;i++)
                    dd.append(dd.VARS, [aNV[i++],aNV[i]])
            }
            if(isDef(v=trc)) dd.append(dd.TRACES, q$.dumpTraces(v))
            if((v=q$.getThrowStackInfo(j.err,bVerb))!="") dd.append(dd.INNER_DEBUG, v)
            var sECN=j.err.getClassName()
            if(sECN!="Error"){dd.append(dd.INFO, [dd.OI_ERROR_CLS,j.err.getClassName()])}

            return dd
            
        } else {
//pc("HERE:\n"+(new Error()).stack);
            var aST, aC, sFN, aA, aV
            sR="JAVASCRIPT DEBUGGER\n"
            sR+=j.msg?j.msg.replace(/\n/g,"\n  ")+"\n\n":""
    
            if(!sFN) {
                try{
                    sFN=funcName(s$(arguments.callee.caller.caller))
                }catch(xx){
                    try{
                        sFN=funcName(s$(arguments.callee.caller))
                    }catch(xx){}
                }
                sR+="Function = "+(isDef(sFN)?sFN:"(unknown)")+"()"
            } else {
                sR+="Function = "+sFN+"("+(aA?aA.join(","):"")+")"
                if(aA){sD+="\n";for(var i=0;i<aA.length;i++){sR+="  "+aA[i]+" = "+(isDef(v=aV[i])?s$(v).abbrev(30):"~")+"\n"}}
            }
            sR+="\nStack:\n"+s$.pad(getStackTrace())
            
            return sR
        }
    }catch(x2){qCoreErr("CORE ERROR IN debugDump()\n\n"+x2)}
    

}


/* STRING */

_SP.trim= new Function("return this.replace(/^\\s+|\\s+$/g,'')")

s$ = function qStringTool(o){if(o instanceof String)return o;try{return String(o)}catch(e){return "Obj No toString Method!: '"+o+"'"}}
_s$P = s$.constructor.prototype
// Static String Properties
s$.FLD_DEL=_SP.FLD_DEL=String.fromCharCode(7);
s$.REC_DEL=_SP.REC_DEL=String.fromCharCode(8);
s$.GRP_DEL=_SP.GRP_DEL=String.fromCharCode(14);
s$.NV_DEL=_SP.NV_DEL=String.fromCharCode(15);
// Static s$ Methods
_s$P.pad = function _s$_pad(sT, sP){ return s$(sT).pad(sP) }

_SP.convlHTMLCharsToNorm=function Str_convlHTMLCharsToNorm() { return this.replace(/\&#13;/g, "\r").replace(/\&#38;/g, "&").replace(/\&#60;/g, "<").replace(/\&#62;/g, ">").replace(/\&#34;/g, "\"").replace(/\&#39;/g, "\'").replace(/\&#10;/g, "\n").replace(/\&nbsp;/g, " ").replace(/\&gt;/g, ">").replace(/\&lt;/g, "<") }
_SP.convSpecialCharsToHtml=function str_convSpecialCharsToHtml() { return (this.replace(/~#10~/g,"<br>").replace(/~#34~/g,"\"").replace(/ /g,"&nbsp;")) }
_SP.convSpecialCharsToNorm=function str_convSpecialCharsToNorm() { return (this.replace(/~#10~/g,"\n").replace(/~#34~/g,"\"")) }
_SP.cleanForHtml=function str_cleanForHtml(s) { return this.replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/\n/g, "<br>").replace(/ /g, "&nbsp;") }
_SP.abbrev=function Str_abbrev(i){var t=this;i=isNaN(i)||i<3?3:parseInt(i);return t.length>i?t.substring(0, i-3)+"...":t.toString()}
_SP.toBool=function Str_toBool(){ var s=this.toLowerCase(); return (s=="false"||s=="")?false:true }
_SP.repList=function Str_repList(aSR) {
  var re, sR=s$(this),ar=arguments
  if(ar.length>1){aSR=qArgToArray(ar)}
  if(!isArray(aSR) || aSR.length%2!=0) { qErr("aSR must be NV array: [S1,R1,S2,R2...]") }
  for(var i=0;i<aSR.length;i++) { re=new RegExp(aSR[i++],"g"); sR=sR.replace(re, aSR[i])}
  return sR
}
_SP.repeat=function Str_repeat(iC) {
    var t=this,sR=""
    for(var i=0;i<iC;i++){sR+=t}
    return sR
}
function qArgToArray(args){
    try {
        if(arguments.length==0)args = arguments.callee.caller.arguments;
        var a=[]
        for(var i=0;i<args.length;i++)a.p(args[i])
        return a
    }catch(x){qErr(x)}
}
_SP.pad = function str_pad(sP){
    if(isUndef(sP)){ sP="  " }
    return sP+this.replace(/\n/g,"\n"+sP);
}
_SP.trim=function String_trim(){; return this.replace(/\s+$/,"").replace(/^\s+/,"") }
_SP.format=function String_format(){var s=String(this),a=arguments; if(a.length==1&&isArray(a[0]))a=a[0]; for(var i=0;i<a.length;i++){s=s.replace(new RegExp("~"+(i+1),"g"),(String(a[i])+""))}; return s }
_SP.remove=function Str_remove(a){  var t=this,s=this.toString(); if(!isArray(a))return; for(var i=0;i<a.length;i++){s=s.replace(new RegExp(s$(a[i]),"g"),"")}; return s}
_SP.toBool=function Str_toBool(){ var s=this.toLowerCase(); return (s=="false"||s=="")?false:true }
_SP.toTitleCase = function str_toTitleCase(){
    var sIn=this,sL,sO="",c,iC,iCL;
    for(var i=0;i<sIn.length;i++){
        iC=sIn.charCodeAt(i);c=sIn.charAt(i)
        if((iC>64&&iC<91) || (iC>96&&iC<123)){
            if(i==0 || iCL < 65 || iCL > 122 || (iCL > 90 && iCL < 97)){
                sO+=(c).toUpperCase()
            } else {
                sO+=(c).toLowerCase()
            }
        } else {
            sO+=c
        }
        iCL=iC
    }
    return sO;
}
_SP.splitJoinedList=function String_splitJoinedList(){
    var t=this; return t.split(t.FLD_DEL)
}
_SP.splitJoinedTable=function String_splitJoinedTable(){
    var t=this,a=t.split(t.REC_DEL),aR=[];
    for(var i=0;i<a.length;i++){aR.p(a[i].splitJoinedList())}
    return aR;
}
/* END STRING */

/* StringBuffer */
StringBuffer = Array;
_AP.a=function sb_append(s){this.p(s);return this};
_AP.ts=function sb_toString(){ return this.join(""); }
/* END StringBuffer */

/* FORM */
function qRegForm(sForm){
    var _f=_d.forms[sForm]
    if(_f==undefined){qErr("rimRegForm error: Cannot find form: "+sForm)}
    if(_f.getElem)return _f
    _f.getElem = function form_getElem(sElem){
        var _f=this,oElem=_f[sElem],aEl
        if(oElem && oElem.name==sElem) return oElem
        //Elem name must start with num :(
        aEl=_f.elements
        for(var i=0;i<aEl.length;i++)
            if(aEl[i].name==sElem) return aEl[i]
        qErr("rimGetFormElem err: Cant find '"+sElem+"' in form "+_f.name) 
    }// Reg method
    return _f
}
function isValidEmail(s) { var r1=new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)"),r2=new RegExp("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"); return (!r1.test(s) && r2.test(s)); }

// Drop Downs
function DDWarn(oDD) {if(!isDD(oDD)){qErr("Object not Drop Down: "+oDD+":"+(oDD.name+oDD.id))}}//NonMoz
function getDDText(oDD) { DDWarn(oDD); return (oDD.selectedIndex>-1)?oDD.options[oDD.selectedIndex].text:"" }
function getDDValue(oDD) { DDWarn(oDD); return (oDD.selectedIndex>-1)?oDD.options[oDD.selectedIndex].value:"" }
function findDDIndex(oDD, sD) { DDWarn(oDD); var ops=oDD.options; for(var i=0;i<ops.length;i++){if(ops[i].text==sD||ops[i].value==sD) {return i}}; return -1}
function findDDIndexAndSet(oDD, sD) { 
    DDWarn(oDD);
    var i=findDDIndex(oDD, sD)
    if(i>-1)oDD.selectedIndex=i;
}


/* Flow Control 
	. Throwable Error for generating non-error logic breaks
*/
function isQExit(o){ return (!o?false:o.__is_QExit?true:false) }
function QExit(){
    var  t=this, args=arguments, v
        ,sWhere="QExit Constructor qOpts"
        ,sMsg, iLvl;
    t.__is_QExit=true;
    switch (args.length) {
        case 0: iLvl=t.NORM; break;
        case 1: if(isInt(v=args[0])){iLvl=v}else{sMsg=v}; break;
        default: sMsg=args[0], iLvl=args[1]
    }
    priv_sMessage = sMsg
    priv_sLevel = iLvl
}
_QEP = QExit.prototype;
_QEP.TRACE  = 0;
_QEP.DEBUG  = 1;
_QEP.INFO   = 2;
_QEP.WARN   = 3;
_QEP.ERROR  = 4;
_QEP.NORM   = 5;
_QEP.isTrace        =function(){ return this.priv_sLevel==this.TRACE; }
_QEP.isDebug        =function(){ return this.priv_sLevel==this.DEBUG; }
_QEP.isInfo         =function(){ return this.priv_sLevel==this.INFO; }
_QEP.isWarn         =function(){ return this.priv_sLevel==this.WARN; }
_QEP.isError        =function(){ return this.priv_sLevel==this.ERROR; }
_QEP.isNormal       =function(){ return this.priv_sLevel==this.NORM; }
_QEP.getMessage     =function() { return this.priv_sMessage; }
_QEP.setMessage     =function(sMsg) { this.priv_sMessage = sMsg; }
/* end Flow Control */


/* Method for making Dynamic JS Calls
   - Usage eval("_fn="+qMakeDynCall("fMth", "aArgArr", aArgArr));_fn()
   Note:
   - This can breaks 'this' calls for objects if not used properly
*/
function qMakeDynCall(sFunc,sVarN,aVarV){
    var s, sC=funcName(arguments.callee.caller)
    s="function "+sC+"_qDynCall (){try{\n  return "+sFunc+"("
    for(var i=0;i<aVarV.length;i++)
        s+=(i==0?"":", ")+sVarN+"["+i+"]"
    return s+")\n}catch(x){qErr(x)}}"
}

/* qOpt Assertable Json Options Container - QOpt */
function QOpt(j){j=(isJson(j)?j:{}); j.__is_QOPT=true; return j } 
function isQOpt(o){ return (!o?false:o.__is_QOPT?true:false) }
function assertQOpt(sVarName, qOptTest){ if(!isQOpt(qOptTest)){qErr("Parameter "+sVarName+" must be a QOpt param object. Caller info: "+q$.getCallerInfo())} }
/* END qOpt */

/* Assertive Gets - Param Assetion and Parsing */
function agetParam(sWhereName, oWhere, sWhat, bRequired, bNoBlank){//debug("called")
    return agetParam_str(sWhereName, oWhere, sWhat, bRequired, bNoBlank)
}
function agetParam_str(sWhereName, oWhere, sWhat, bRequired, bNoBlank){//debug("called")
    var sVal = null
    sVal=agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(sVal))return ""
    if(bNoBlank){
        sVal = s$(sVal).trim();
        if(bNoBlank && sVal=="") {
            qErr("Parameter '"+sWhat+"' in "+sWhereName+" cannot be blank (empty)!");
        }
    }
    return sVal
    
}
function agetParam_obj(sWhereName, oWhere, sWhat, bRequired){
    var oVal, bIsNv,sClz

    // API Assertions
    try {
	    bIsNv=(isArray(oWhere)&&!oWhere.isDb1Table)
	    if(isUndef(sWhereName)||isUndef(oWhere)||isUndef(sWhat)){ qErr("Required Params: sName, oWhere, sWhat"); }
	    if(bIsNv&&!isNVArray(oWhere)){ qErr("Param oWhere is not a NV Array"); }
	    if(bIsNv){
	        for(var i=0;i<oWhere.length; i++) {
	            if ( sWhat==oWhere[i] ) {
	                oVal= oWhere[i+1];
	                break;
	            }
	        }
	    }else{
	    	sClz=oGetClassOf(oWhere).toLowerCase()
	    	if(sClz==="parseduri"){
	        	oVal = oWhere.getParam(sWhat, true)
	        } else {
	        	oVal = oWhere[sWhat]
	        }
	        	
	    }
	    if(isUndef(oVal)){
	        if(bRequired){
	            qErr("Parameter '"+sWhat+"' in "+sWhereName+" is required but is null (missing)!");
	        } else {
	            return JNull();
	        }
	    }
	}catch(x){qErr(x,{varDump:{"args":q$.dumpArgs()}})}
    return oVal;   
}
function agetParam_bool(sWhereName, oWhere, sWhat, bRequired){
    var oVal = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(oVal)){return false}
    if(!isBool(oVal)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not a boolean! Value="+oVal)}
    return s$(oVal).toBool()
}
function agetParam_int(sWhereName, oWhere, sWhat, bRequired){
    return parseInt(agetParam_num(sWhereName, oWhere, sWhat, bRequired))
}
function agetParam_num(sWhereName, oWhere, sWhat, bRequired){
    var i = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(i)){return -1}
    if(isNaN(i)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not a number! Value="+i)}
    return i
}
function agetParam_json(sWhereName, oWhere, sWhat, bRequired){
    var oVal = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(oVal)||oVal===""){return JNull()}
    if(!isJson(oVal)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not a json! Value="+oVal)}
    return oVal||{}
}
function agetParam_arr(sWhereName, oWhere, sWhat, bRequired){
    var oVal = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    try{if(isJNull(oVal)){return []}}catch(x){}
    if(!isArray(oVal)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not an array! Value="+oVal)}
    return oVal||[]
}
function agetParam_func(sWhereName, oWhere, sWhat, bRequired){
    var oVal = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(oVal)){return new JNull()}
    if(!isFunc(oVal)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not an Function! Value="+oVal)}
    return oVal
}
function agetParam_elem(sWhereName, oWhere, sWhat, bRequired){
    var oVal = agetParam_obj(sWhereName, oWhere, sWhat, bRequired)
    if(isJNull(oVal)){return new JNull()}
    if(!isElem(oVal)){qErr("Parameter '"+sWhat+"' in "+sWhereName+" is not an Element! Value="+oVal)}
    return oVal
}
/* end Assertive Gets */




/* XML Http (AJAX) */
function qCreateHttpRequest() {
    if(is.ie) { return new ActiveXObject("Microsoft.XMLHTTP"); } else { return new XMLHttpRequest; }
};
function qCheckUrl(sUrl){ var x = qCreateHttpRequest();x.open("HEAD", sUrl, false); x.send(null); return (x.status==200); }


/* CSS / GUI STUFF */
function qSetOpacity(o,iPcnt){ if(is.ie){ o.style.filter="alpha(opacity="+iPcnt*100+")"; } else { o.style.opacity=(iPcnt==1?"1.0":iPcnt); } }


/* OBJECT */
function oGetClassOf(o){
    if(o==undefined){return "(undefined)" }
    var a=/function\s+(.+)\s*\(.*\)\s*\{/.exec(o.constructor)
    return (a && a[1] ? a[1] : "(unknown)")
}
function qObjCopyProp(oFr,oTo,aPr){ var n,v;for(var i=0;i<aPr.length;i++){n=aPr[i];if(isDef(v=oFr[n])){oTo[n]=v}}}
function qObjGet(o,bSort){var t=o,n=qObjListProps(t,bSort),a=[]; for(var i=0;i<n.length;i++){a.p(n[i]);a.p(t[n[i]])};return a}
function qObjListProps(o,bSort){ 
    var a=[]; 
    for(n in o){
        try {
            if(isDef(n)&&!isFunc(o[n])&&isNaN(n)){
                a.p(n)
            }
        } catch(x){
           pc(debugDump("Failed on n = "+n+", o = "+o+". Err = ",x))
        }
    }; 
    if(o&&isDef(o.length)){for(var i=0;i<o.length;i++)a.p(i);}
    return bSort?a.sort():a
}
function qObjListMethods(o){ var a=[];
    try {
        for(n in o){
            try {
                if(isFunc(o[n])){a.p(n)}
            }catch(x){
                pc(debugDump("Failed on n = "+n+", o = "+o+". Err = ",x))
            }
        }; 
        return a.sort() 
    }catch(x){
        debugErr(x)   
    }
}

function qDumpObj(o,j){
    var hr="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", aN, sR="",v
        ,sLbl=(j?(j.lbl||null):null)
        ,iAbbrAt=( (isNum(v=(j?j.abbrAt:null))?v:null) ||-1 )
        ,aProps=qObjListProps(o,true)
    ;
    
pc("!!! qDumpObj !!!")
    
    sR+=hr+"\n Obj Dump Start"+(sLbl?" for "+sLbl:"")+"\n"+hr+"\n"
    if(isUndef(o)){sR+="(null)";}else{
	    sR+=" Properties:\n"; if(aProps.length==0){sR+=" . toString: "+o.toString()+"\n"}else{__(aProps)}
	    sR+=" Functions / Method:\n"; __(qObjListMethods(o),true)
	}
    sR+=hr+"\n Obj Dump End\n"+hr

    return sR
    function __(aN,bIsFunc){
        if(aN.length==0)sR+=(". (none)\n")
        for(var i=0;i<aN.length;i++){
            ___(aN[i],(bIsFunc?undefined:o[aN[i]]))
        }
        function ___(n,v){
            try {
                sR+=(" . "+n+(bIsFunc?" - "+funcName(o[n])+"()":" = "+v)+"\n")
            } catch(x){
               sR+="Failed on n = "+n+", v = "+v+", bIsFunc = "+bIsFunc+". Err = "+x.message
            }
        }
    }
};qObjDump=qDumpObj

/**
 * qCore:qObjClone
 * - Concatenate two Objects and return new
 * - params in j2 starting with $app (case sensitive) will be appended
 * - args:
 * - . (Obj, [QOpt]) <~ Just clone single object
 * - . (Obj1, Obj2, [QOpt]) <~ Clone Obj1 and Obj2
 * - . QOpt (Options):
 * - - . (none defined)
 * - Note: Does recurse down children!
 * - todo: Add Options capability
 **/
function qObjClone(){
    var ar=arguments,iA=ar.length,
        j1,j2,jO,jR={},v,n2
//pc("args = "+q$.dumpArgs())
    j1=ar[0]
    if(iA>0){
        if(isQOpt(ar[1])){
            jO=ar[1]
        }else{
            j2=ar[1]
            if(isQOpt(ar[2])){ jO=ar[2] }
        }
    }   
    for(n in j1) jR[n]=j1[n]
    for(n in j2){v=j2[n]
//pc("n = "+n)
        if( s$(n).indexOf("$app")==0 ){
            n2=n.substring(4,v.length)
            jR[n2]=(isDef(jR[n2])?jR[n2]+" ":"")+v
//pc(
//    "\n v.substring(4,v.length) = "+n.substring(4,v.length)
//   +"\n n2 = "+n2
//   +"\n jR[n.substring(4,v.length)] = "+jR[n2]
//   +"\n args:\n"+s$.pad(q$.dumpArgs())
//)
        } else {
            jR[n]=v
        }
    }
//qErr(qObjGet(jR).join(" | "))
    return jR
}


/**
 * qCore:qObjAppend
 * - Appends Params from Second Object to first
 * - params in j2 starting with $app (case sensitive) will be appended
 * - args:
 * - . (Obj1, Obj2, [QOpt]) <~ Clone Obj1 and Obj2
 * - . QOpt (Options):
 * - - . (none defined)
 * - oBase is modified and is not required to be returned
 **/
function qObjAppend(){
    var ar=arguments,iA=ar.length,
        oBase,j2,jO,jR={},v
    oBase=ar[0];j2=ar[1];jO=ar[2]
    if(!isObj(oBase)||!isObj(j2)||(isDef(jO)&&!isQOpt(jO))){qErr("Invalid Arg(s)")}
    for(n in j2){v=j2[n]
        if( s$(n).indexOf("$app")==0 ){
            n2=n.substring(4,v.length)
            oBase[n2]=(isDef(oBase[n2])?oBase[n2]+" ":"")+v
        } else {
            oBase[n]=v
        }
    }
}


/* ARRAY */
_AP.has=function Array_has(s){var t=this; for(var i=0;i<t.length;i++){if(t[i]==s){return true}};return false}//returns true if Array contains 'Element'
_AP.p=function Array_p(o) { var args=arguments;for(var i=0;i<args.length;i++){this.push(args[i]);} }
_AP.clean=function Array_clean(){var t=this; if(!t.length){return this}; if(isUndef(this[t.length-1])){t.pop()}; if(t.length==1&&t.join(",").replace(/,/g,"")==""){t.pop()}; return this}//Fix for IE Arrays && Fix for Null Array (One blank record)
_AP.toJson=function Array_toJson(jArgs){
	var t=this,jR={},n,v,s,aN=[],aNC=[],iN;
	jArgs=jArgs||{};
	if(t.length==1&&!t[0]){return jR}
	if((t.length%2)!=0){qErr("This must be [n1,v1,n2,v2...]:\nlength="+t.length+"\ncontains:"+t+"\n"+t.length%2)}
	for(var i=0;i<t.length;i++){
	  s=s$(t[i]); n=!(jArgs.forceLower)?s:s.toLowerCase(); v=t[++i];
	  if((iN=aN.find(n))>-1){
	    if(aNC[iN]==1){
	    	jR[n]=isArray(jR[n])?jR[n].clone():[jR[n]];
	    	__();
	    	aNC[iN]++;
	    }else{
	    	__();
	    }
	  }else{
	  	jR[n]=v;
	    aN.p(n);
	    aNC[aN.find(n)]=1;
	  }
	}
	
	return jR
	function __(){if(isArray(v)){for(var i=0;i<v.length;i++){jR[n].p(v[i]) }}else{jR[n].p(v)}}
}

_AP.find=function Array_find(s){var t=this; for(var i=0;i<t.length;i++){if(t[i] == s) {return i}}; return -1}//if 's' exists return the index else -1
_AP.findLast=function Array_findLast(s){var t=this; for(var i=t.length-1;i>-1;i--){if(t[i] == s) {return i}}; return -1}//if 's' exists return the index else -1

_AP.group=function Array_group(iG) {// Builds a 2 Dim array [this.length/i][i] from 1 Dim
  var t=this;if(isNaN(iG) || t.length%iG!=0) { qErr("Integer passed not valid: t.length=~1, t=~2".format(t.length,t)); return };var a=[], aa=[], i =0;for(var i=0;i<t.length;i++) {aa.push(t[i]);if(!((i+1)%iG)) { a.push(aa); aa=[] }};return a
}
_AP.remove=function Array_remove(s,bAll){
    var t=this,iF=t.find(s);
    if(iF==-1){return false}; if(iF>-1){t.slice(iF)};
    if(bAll){t.remove(s,bAll);}
}



/* PARSED URI*/
function ParsedURI(s) {
  var 
     t=this
    ,s=(isUndef(s)||s=="")?location.href:s
    ,iPI,iAI,sU=iAI,sA,iSPI,sSP,iPoI,aPa,aP,o,iPlen=4
  ;
    
  iPI=s.indexOf(":///")
  if(iPI==-1){
      iPI=s.indexOf("://")
      iPlen=3
  }
  iAI=s.indexOf("?")
  sU=iAI==-1?s:s.substring(0,iAI)
  sA=iAI==-1?"":s.substring(iAI+1,s.length)
  iSPI=sU.indexOf("/",iPI==-1?0:iPI+iPlen)
  sSP=sU.substring(iPI==-1?0:iPI+iPlen,iSPI)
  iPoI=sSP.indexOf(":")
    
  t.Protocol=iPI==-1?"":sU.substring(0,iPI)
  t.Site=sSP.substring(0,iPoI>-1?iPoI:sSP.length)
  t.Port=iPoI==-1?"":sSP.substring(iPoI+1,iSPI>-1?iSPI:sU.length)
  t.Path=sU.substring(iSPI,sU.length)
  t.Params=[]; aPa=s$(sA).split("&")
  for(var i=0;i<aPa.length;i++){aP=aPa[i].split("=");if(aP.length==2){ 
    try{// First attempt utf-8 decode
        t.Params.push(new ParsedURIParam(decodeURIComponent(aP[0]), decodeURIComponent(aP[1])))
    }catch(e){// If char is high ascii (128-255) and is not escaped as utf-8, decodeURIComponent will fail. unescape() will attempt deprecated non-utf-8 method of decoding.
        t.Params.push(new ParsedURIParam(unescape(aP[0]), unescape(aP[1])))
    }
  }}
}
_PUP=ParsedURI.prototype
_PUP.findParam=function PU_findParam(s) {
	var p=this.Params;
	for(var i=0;i<p.length;i++) { if(p[i].Name==s) { return i } }; 
	return -1 
}
_PUP.getParam=function PU_getParam(s, bAssert) {
	var t=this,p=t.Params,iF=t.findParam(s); 
	if(iF==-1){return bAssert?null:""};
	return p[iF].Value;
}
_PUP.popParam=function PU_popParam(s) {
	var t=this,p=t.Params,iF=t.findParam(s); 
	if(iF==-1){return};
	return p.splice(iF,iF);
}
_PUP.pushParam=function PU_pushParam(n,v) { var i,p=this.Params; if(isUndef(n) || isUndef(v) || n=="") { qErr("n or v cannot be null or blank!") }; for(var i=0;i<p.length;i++) { if(p[i].Name==n) { p[i]=(new ParsedURIParam(n, v)); return } }; p.p(new ParsedURIParam(n, v)) }
_PUP.setParam=function PU_setParam(n,v) {this.pushParam(n,v)}
_PUP.getURL=function PU_getURL() { var t=this,p=t.Protocol; return encodeURI(p+"://"+this.Site+(p=="file"?"":":")+this.Port) }
_PUP.getURI=function PU_getURI(bGetURL) {
    try{ 
        var 
            t=this
           ,sURI=(bGetURL?t.getURL():"")+t.Path
        ; 
        for(var i=0;i<t.Params.length;i++){
            if(i==0){sURI+="?"}else{sURI+="&"};
            sURI+=encodeURIComponent(t.Params[i].Name)+"="+encodeURIComponent(t.Params[i].Value)
        }
    }catch(e){
        qErr(e)
    }
    return sURI
}
_PUP.updateRand=function PU_updateRand(){var t=this; t.setParam("__r", nRand(4))}
_PUP.toString=function ParsedURI_toString(){ return this.getURI() }
function ParsedURIParam(n, v) { var t=this; t.Name=n; t.Value=v }
/* end parsed uri*/



/* CONSOLE - Needs qConsole.html*/
function startCons(j){
    if(isBool(j))j={cb:j};
    if(is.wk){
        setTimeout("_w.consoleLoaded()",100)
        return;
    }
    if(!_w.wrroot||wrroot=="")qErr("wrroot is not defined or empty!!");
    q$.__pcNoDate=j.d;
    _w._wCons=_w.open("~1qConsole.html~2".format(wrroot,j.cb?"?Callback=true":""),"Console_"+nRand(10),"height="+(j.h||600)+", width="+(j.w||550)+", top="+(j.t||10)+", left="+(j.l||60)+", resizable=yes, menubar=yes, scrollbars=yes, status=yes, titlebar=no, toolbar=no");
}
function clearCons(){ 
    if(is.wk){qErr("WebKit not supported");}
    try {_w._wCons.clearCons()}catch(x){} }
function plog(s){
    try{
        var fn = is.wk?console.log:_w._wCons.pCons
        fn("[ "+q$.getCallerInfo()+" ]<br>&nbsp;.&nbsp;"+s)
    }catch(e){}
}

/* Note: Mozilla 14.01 implemented new stack structure: See 744842  */
function parseMozStack(err,bShowAll){
    var m,iL,sF,oH,sP,iF,sR,aR=[],sRow,sStack,a
    sStack=err.stack

    a=sStack.split("\n")
    for(var i=0;i<a.length;i++){sRow=a[i];
        m = /^\s*(.*)@(.*):(\d+)\s*$/gm.exec(sRow)
        if(m==null){
            pc("Un-parsable item: `"+sRow+"`");
        } else {
            iL=m[3] // Line Num
            if((sF=m[1]) && is.verMajor<14){ sF=sF.substring(0,sF.indexOf("(")) } // Method parse
            if(bShowAll||!__qSkipStack.has(sF)){
                oH=new ParsedURI(m[2]); // Parse Path & Resource
                sP=oH.Path; if((iF=sP.lastIndexOf("/"))==-1){ sR=sP; sP="" }else{ sR=sP.substring(iF+1,999); sP=sP.substring((oH.Protocol=="file"?1:0),iF+1) }
                aR.p([ sF, [], [], sR, sP, iL ])
            }  
            
// pc(
   // "\n sRow:\n"+sRow
  // +"\n m:\n"+m
// )
        }
    }
// pc(q$.dump(aR))
    return aR
}

/*
WebKit error parser logic

Sample Error:

Error
    at pc (file:///C:/_data/lsr_qlibjs/source/war/webres/common/qCore.js:1530:74)
    at s$Tests (file:///C:/_data/lsr_qlibjs/source/war/webres/common/_test/qCore_gen_tester.html:64:13)
    at bodyLoaded (file:///C:/_data/lsr_qlibjs/source/war/webres/common/_test/qCore_gen_tester.html:33:15)
    at eval at __start (file:///C:/_data/lsr_qlibjs/source/war/webres/common/_test/qCore_gen_tester.html:86:176)
    at __start (file:///C:/_data/lsr_qlibjs/source/war/webres/common/_test/qCore_gen_tester.html:86:171)
    at file:///C:/_data/lsr_qlibjs/source/war/webres/common/_test/qCore_gen_tester.html:86:212
    at unknown source
    
    Patterns:
        (1) <  at pc (URL...>
        (2) <  at eval at (URL...>
        (3) <  at URL...>
        (4) <  at unknown source>
*/    

function parseWkStack(err,bShowAll){
    var bGood,bFail,m,m2,iL,sF,oH,sP,iF,sU,sR,sT,aR=[],sRow,sStack,a
    sStack=err.stack
//console.log("sStack = '"+sStack+"'")
    a=sStack.split("\n")
    for(var i=1;i<a.length;i++){sRow=a[i];
        bGood=bFail=false;
      // Find Patter (1)
        m = /^\s*(at)\s(.*)\s(\()(.*)$/gm.exec(sRow)
        if(m!=null){
            bGood=true;
            sF=m[2] // Method parse
            __m2(m[4])
        } else {
          // Find Patter (2)
            m = /^\s*(at eval at)\s(.*)\s(\()(.*)$/gm.exec(sRow) 
            if(m!=null){
                bGood=true;
                sF=m[2] // Method parse
                __m2(m[4])
            } else {
                if(sRow.indexOf("at unknown source")>-1){// Ignore
                    bGood=false
                } else {
                  // Find Patter (3)
                    m = /^\s*(at)\s(.*)$/gm.exec(sRow) 
                    if(m!=null){
                        bGood=true;
                        sF="chrome" // Method parse
                        __m2(m[2])
                    } else {
                        console.log("Un-parsable WebKit Stack Line: '"+sRow+"'");
                    }
                }

            }

        }
        if(bGood){
            if(bShowAll||!__qSkipStack.has(sF)){
                oH=new ParsedURI(sU); // Parse Path & Resource
                sP=oH.Path; if((iF=sP.lastIndexOf("/"))==-1){ sR=sP; sP="" }else{ sR=sP.substring(iF+1,999); sP=sP.substring((oH.Protocol=="file"?1:0),iF+1) }
                aR.p([ sF, [], [], sR, sP, iL ])
            }  
        }
    }
    function __m2(s){
        m2 =  /^(.*)(:)(.*)(:)(.*)$/gm.exec(s)
        if(m2==null){
            console.log("Un-parsable WebKit Stack Line: '"+sRow+"'");
        } else {
            sU=m2[1] // URL to source
            iL=m2[3] // Line Num
            bGood=true;
        }
    }
    return aR
}

__pcBuffer=[]
__pcStack=[]
function pc(s){//alert("called: "+s)
    var
        sCInf,aST,sTmp,i1,i2,r,sO,sFunc,args=arguments,d,sMs,sD="",iS,iM,iMS,v,aST,w
       
    if(_w.__hadPCCoreErr)return;
    try{
        
      // First get Caller (raw)
        sFunc=funcName(args.callee.caller);sCInf=sFunc+"()"
        
        if(["parseMozStack","parseWkStack","qdbg_compileStack","getStackTrace"].has(sFunc)){
            aST=[]
        } else {
            if(!is.ie){
                aST=is.moz?parseMozStack(new Error(), true):parseWkStack(new Error(), true);
                try {
                    sTmp=aST[1][stFunc]
                    if(sTmp!=sFunc)
                        sCInf+="- ~"
                    else{
                        sCInf = q$.compileStack([aST[1]]).repList(["\n","","\r",""])
                        sFunc=sTmp
                    }
                }catch(x){}
            }else {
                aST = getStackTrace(new Error(), true, {showAll: true})
            }
        }
        
        s=s$(s).repList(["<","&lt;","<","&gt;"])

        s = (s.length<10)?" "+s:("\n"+s$.pad(s,".  ")+"\n")

        sO="[ "+sCInf+" ]"+s
        if(is.wk||!q$.__pcNoDate){
            d=new Date();sMs=s$(d.getTime())
            iS=parseInt(d.getSeconds())
            iM=parseInt((d=new Date()).getMinutes())
            iMS=parseInt(sMs.substring(sMs.length-3))
            sD=(iM<10?"0":"")+iM+":"+(iS<10?"0":"")+iS+","+(iMS<10?"00":iMS<100?"0":"")+iMS+" "
        }
        var iPad=aST.length-2
        sO=s$.pad(sO, sD+s$("-").repeat(iPad));
		
        if(is.wk){
            console.log(sO)
        } else if(!(w=_w._wCons) || !winTest(w)){
            __pcBuffer.p(sO)
        } else {
            if(__pcBuffer.length>0){
                for(var i=0;i<__pcBuffer.length;i++)
                    w.pCons(__pcBuffer[i])
                __pcBuffer=[]
            }
            __(sO)
        }
    }catch(e){
        _w.__hadPCCoreErr=true
        alert("!!Core Error!! function=pc() Call Failed.\nmsg="+e.message+"\nstack="+e.stack)
    }
    function __(s){_w._wCons.pCons(s)}
}

// Console Logging (new)
// . ConsoleWrapper is for IE and other non console browsers
// . c$ is a pointer to console object
function ConsoleWrapper(){}
ConsoleWrapper.prototype.log=function consoleWrapper_log(s){pc(s)}
c$=_w.console&&_w.console.log?_w.console:new _w.ConsoleWrapper();

/* DOM */
function getElem(id){
    if(typeof(id)!='string') return id// Assuming that id is an Element
    var oE=_d.getElementById(id)
    return oE
}
function agetElem(id){try{
    var o;if(o=getElem(id)){return o}else{qErr("Invalid id Passed `"+id+"`")}
}catch(xx){qErr(xx)}}

function dw(s){document.write(s)}
function dwE(sHtml,j1,j2){ dw(mkE(sHtml,j1,j2)) }

/* Make Elem Html */
function mkE(sHtml,j1,j2){
    var
        ar=arguments,iA=ar.length
       ,j3,sN,v,sR,sP,bClose=true
       ,sC1,sC2,sb=new StringBuffer()
    ;
  // Process Args
    if(iA==1){ 
        j1=sHtml; bClose=false 
    } else if(iA==2 && isJson(sHtml)){ 
        j2=j1; j1=sHtml; sHtml=""; bClose=false; 
    }

    sb.a((j1.nl?"\n":"")+"<"+(j3=qObjClone(j1,(j2?j2:{}))).tag)
    for(n in j3){
        v=s$(j3[n]);
        sC1 = n.charAt(0);
        if(sC1=="$"){
            sC2=n.charAt(1);
            if(sC2=="h"){sHtml=v; bClose=true; continue;}else if(sC2=="c"){n="_class";sC1="_";}else if(sC2=="s"){n="_style";sC1="_";}
        }
        if(sC1==="_"){
//if(_w.__DBG && n=="_value"){
//    pc(
//         "\n v = `"+s$.pad(v)+"`"
//        +"\n v(rep) = `"+v.replace(/\n/g,"\\\n").replace(/\"/g, "&#34;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
//    );
//}
//if(_w.__dbg)pc("n = "+n+", v = "+v)
            v=v.replace(/\n/g,"\\\n").replace(/\"/g, "&#34;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
            sb.a(" ").a(n.substring(1,n.length)).a("=\"").a(v).a("\"")
        }
    }

    return sb.a((bClose?(">"+sHtml+(j1.nl?"\n":"")+"</"+j3.tag+">"):(j1.open?">":"/>"))).ts()
}
function getTitleElem(w){ var el; try{el=w.document.getElementsByTagName("title")[0]}catch(x){return JNull()}; return el }

function qGetScrollLeft(o){ return priv_qGetScrollLT(o, false) }
function qGetScrollTop(o){ return priv_qGetScrollLT(o, true) }
function priv_qGetScrollLT(o,bTop){
    var sPar=(bTop?"scrollTop":"scrollLeft"),iOfs=0,sTN=o.tagName,bWin=isDef(o.setInterval)
    if (bWin || o == _d || (sTN=sTN.toLowerCase()) == 'html' || sTN == 'body') {
        var w=((bWin && o)?o:_w),wd=w.document,wdb=wd.body,wde;
        if((wde=wd.documentElement) && wde[sPar]){ iOfs=wde[sPar] }else if(wdb && isDef(wdb[sPar])){ iOfs=wdb[sPar] }
    } else {
        if (isDef(o[sPar])){ iOfs = o[sPar]  }
    };
    return iOfs; 
}

function getMouseCoords(e){
    var _db=_d.body,de=_d.documentElement;
    if(!is.ie){ xy = {x:e.pageX-0.5, y:e.pageY-0.5}; } else { xy = {x:e.clientX + de.scrollLeft - 2, y:e.clientY + de.scrollTop - 2} }
    return xy
}
function getElemPosition(o){
    var l=0,t =0;
    while (o.offsetParent){l += o.offsetLeft;t += o.offsetTop;o  = o.offsetParent;}
    l += o.offsetLeft;t += o.offsetTop;
    return {x:l, y:t};
}
function mouseIsOver(e,o){
	var xyEl=getElemPosition(o),xyM=getMouseCoords(e),iElH=o.offsetHeight,iElW=o.offsetWidth
		,iTL=xyEl.x,iTR=iTL+iElW,iBL=xyEl.y,iBR=iBL+iElH,x,y
//pc(
//     "\n xyEl = "+q$.dump(xyEl).replace(/\n/g, ", ")
//    +"\n xyM = "+q$.dump(xyM).replace(/\n/g, ", ")
//    +"\n iElH = "+iElH
//    +"\n iElW = "+iElW
//    +"\n (xyEl.x+iElW) = "+(xyEl.x+iElW)
//    +"\n (xyEl.y+iElH) = "+(xyEl.y+iElH)
//);	
	return (x<xyEl.x||x>(xyEl.x+iElW)||y<xyEl.y||y>(xyEl.y+iElH))?false:true
}
function hideElem(o){o.style.visibility="hidden"}
function showElem(o,x,y){var os=o.style; os.visibility="visible";if(arguments.length==3){os.top=y+"px";os.left=x+"px"}}



function remTextNodes(a){ var aR=[]; for(var i=0;i<a.length;i++){ if(a[i].nodeName!="#text"){ aR.p(a[i]) } }; return aR }
function setTextNodeSplit(id,sVal){setTextNode(id,sVal,true)}
function setTextNode(id,sV,b){var oN=getElem(id),oP,a; if(!oN) { qErr("Invalid HTML Element '"+id+"'")}; a=b?s$(sV).replace(/<br>/g, "\n").split("\n"):[s$(sV)]; id.innerHTML=""; oP=_d.createElement("p"); for(var i=0;i<a.length;i++){oP.appendChild(_d.createTextNode(a[i]));if(i<a.length-1){oP.appendChild(_d.createElement("br"))}}; if(oN.hasChildNodes()){oN.replaceChild(oP, oN.firstChild)}else{oN.appendChild(oP)}}
/* END DOM */





/*
    QDATE
    . Parses dates, Localizes Date, Fixes IE TZ codes. method args:  true=long default/false=short
    . Also greatly simplifies the date inteface
    TODO:
    . [.] Put this code on a diet
*/
function QDate(sD,bDateOnly){this.parse(sD,bDateOnly)}
 _QDP=QDate.prototype
 _QDP.parse=function PD_parse(sD,bDateOnly){
//	 pc("sD="+sD)
     var t=this,aC=_w.__aTZCodes,d,aFD,sTime
     t.initValue=sD
     t.dateOnly=bDateOnly
     t.isQDate=true
     if(sD){
        t.isNull = (sD===q$.NULLDATE||sD==="-")
        if(!t.isNull){
            aFD=__fd(s$(sD))
            sD=s$(new Date(aFD.join(" ")))
            if(is.ie)sD=__ctz(sD);
            t.timeZone=sD.substring(sD.indexOf("GMT"),sD.indexOf("GMT")+9)
            t.date=d=new Date(sD)
        }

     }else{
        t.date=d=new Date()
        var i=(d.getTimezoneOffset()/60)*100,iAbs=Math.abs(i)
        t.timeZone="GMT"+(i>0?"+":"-")+(iAbs<100?"00":iAbs<1000?"0":"")+iAbs
        sD=s$(d)

     }

     if(!t.isNull){
         t.parseValue=sD
         t.isValid=isNaN(d.getDate())?false:true
         t.ms=d.valueOf()
     }
//pc(
//    "\n t.date = "+t.date
//   +"\n t.timeZone = "+t.timeZone
//   +"\n t.isNull = "+t.isNull
//   +"\n t.isValid = "+t.isValid
//   +"\n t.initValue = "+t.initValue
//   +"\n sD = "+sD
//   +"\n stack:\n"+s$.pad(getStackTrace())
//)
     function __ctz(sD){return sD.repList([" UTC "," GMT+0000 ","PDT","GMT-0700","PST","GMT-0800","MDT","GMT-0600","MST","GMT-0700","CDT","GMT-0500","CST","GMT-0600","EDT","GMT-0400","EST","GMT-0500","UTC","GMT"])}
     function __fd(s) {//Normalizes [m||d]/[d||m]/[yy||yyyy]
        try{
             if(!isStr(s)){s=s$(s)}
             var 
                a=s.match(/(^\d{1,4})[\/|-](\d{1,2})[\/|-](\d{1,4})(.*)/)
                ,y,m,d,sY,sTime
             if(!a){return [s]};m=a[1];d=a[2];y=parseInt(a[3]);sTime=s$(a[4]).trim()
             if(m>12){if(d>12){return ["BAD"]};d=m;m=a[2]}
             if(m<1||m>12||d<1||d>31){return ["BAD"]}
             switch ((sY=s$(y)).length){
                 case 1: y="200"+sY; break
                 case 2: y=y<70?2000+y:1900+y; break
                 case 3: return ["BAD"]
             }
             return sTime?[m+"/"+d+"/"+y,sTime]:[m+"/"+d+"/"+y]
         }catch(e){ qErr("Failed fixing date. s = `"+s+"`, class(s) = `"+oGetClassOf(s)+"`", e) }
     }
 }
 _QDP.getWeekDay=function PD_getWeekDay(b){ var t=this,d=t.date,i=d.getDay(),s; if(!t.isValid)return; s=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][i]; return !s?null:(!b?s:(s?s.substring(0,3):s))}
 _QDP.getYear=function PD_getYear(b){return this.format(b?"yy":"yyyy")}
 _QDP.getMonth=function PD_getMonth(b){var t=this,d=t.date,i=d.getMonth(),s; if(!t.isValid)return; return getMonthText(t,b)}
 _QDP.getDay=function PD_getDay(b){return this.format(b?"dd":"d")}
 _QDP.getHour=function PD_getHour(b){var t=this,i=t.getHour24(); if(!t.isValid)return; i=(i==12?12:i>11?i-12:i); return (b&&i<10?"0":"")+i}
 _QDP.getHour24=function PD_getHour24(){return this.date.getHours()}
 _QDP.getMinute=function PD_getMinute(b){return this.format(b?"mm":"m")}
 _QDP.getSecond=function PD_getSecond(b){return this.format(b?"ss":"s")}
 _QDP.toString=function PD_toString(bNoTime){var t=this;return t.isNull?"-":!t.isValid?"Invalid Date: "+t.initValue:t.format(t.dateOnly||bNoTime?q$.SDF_dateOnly:q$.SDF_dateTime);}
function getDaysInMonth(iM,iY){var d=new Date(iM+"/32/"+iY); return 32-d.getDate()}
function getMonthText(v,b){var i=(v.isQDate?v.date.getMonth():v.getFullYear?v.getMonth():v),s; s=["January","February","March","April","May","June","July","August","September","October","November","December"][i]; return !s?null:(!b?s:(s?s.substring(0,3):s))}

 _QDP.getDaysInMonth=function PD_getDaysInMonth(){ var t=this,d=new Date(t.format("M/32/yyyy")); return 32-d.getDate() }
 _QDP.zeroTime=function PD_zeroTime(){ var t=this; return new QDate((t.date.getMonth()+1)+"/"+t.date.getDate()+"/"+t.date.getFullYear()) }
 
/* Date Add - Still needs work! */
// (n,v) or ([n1,v1,n2,v2...]) - Is not perfect - Assumes 30.44 days in month & DST has affects as well
 _QDP.dateAdd=function PD_dateAdd(nv,v){ 
     var t=this,d=0,w=0,m=0,y,iD=86400000,iAY;
     if(!t.isValid){return};
     if(isStr(nv)&&isNum(v)){nv=[nv,v]};
     if(!isArray(nv)){qErr("nv must be [n,v,...]")};
     nv=nv.toJson({forceLower: true}); 
     d=(parseFloat(nv["d"])||0)+((parseFloat(nv["w"])||0)*7); 
     if(d!=0){ t.date.setDate(t.date.getDate()+d) }
     m=(parseFloat(nv["m"])||0)+t.date.getMonth()+1;
     y=(parseFloat(nv["y"])||0);    
     if(m!=(t.date.getMonth()+1)){
        y+=parseInt(m/12)
        m+=m%12
     }
     return new QDate(m+"/"+t.date.getDate()+"/"+((parseInt(y)+parseInt(t.date.getFullYear()))))
 }
 _QDP.getDaysUntil=function PD_getDaysUntil(sD){
     var d=new QDate(sD),t=this
     if(!d.isValid){qErr("Date invalid: "+sD)}
     return parseInt((d.ms-t.ms)/86400000)+1
 }
 // Follows Java API SimpleDateFormat
 _QDP.format=function PD_format(s){
    if(!s)return qErr("s is undefined!")
    var 
        t=this,iF=1,aF=[],sRet,d=t.date 
        x=[
             {n:"yyyy"  ,e:"t.date.getFullYear()"}
            ,{n:"yy"    ,e:"s$(t.date.getFullYear()).substring(2,4)"}
            ,{n:"MMMM"  ,e:"t.getMonth()"}
            ,{n:"MMM"   ,e:"t.getMonth(true)"}
            ,{n:"MM"    ,e:"((v=t.date.getMonth())<9?'0':'')+(v+1)"}
            ,{n:"M"     ,e:"t.date.getMonth()+1"}
            ,{n:"dd"    ,e:"((v=t.date.getDate())<10?'0':'')+v"}
            ,{n:"d"     ,e:"t.date.getDate()"}
            ,{n:"EE"    ,e:"t.getWeekDay()"}
            ,{n:"E"     ,e:"t.getWeekDay(true)"}
            ,{n:"a"     ,e:"t.getHour24()>11?'PM':'AM'"}
            ,{n:"HH"    ,e:"((v=t.getHour24())<10?'0':'')+v"}
            ,{n:"H"     ,e:"t.getHour24()"}
            ,{n:"hh"    ,e:"t.getHour(true)"}
            ,{n:"h"     ,e:"(v=t.getHour())!=0?v:12"}
            ,{n:"mm"    ,e:"((v=d.getMinutes())<10?'0':'')+v"}
            ,{n:"m"     ,e:"d.getMinutes()"}
            ,{n:"ss"    ,e:"((v=d.getSeconds())<10?'0':'')+v"}
            ,{n:"s"     ,e:"d.getSeconds()"}
            ,{n:"S"     ,e:"(v=s$(t.ms)).substring(v.length-3,v.length)"}
            ,{n:"z"     ,e:"t.timeZone?t.timeZone:''"}
            ,{n:"Z"     ,e:"t.format('z')"}
        ]
    if(t.isNull){return q$.NULLDATE};
    if(!t.isValid){return t.toString()};
    for(var i=0;i<x.length;i++){ 
        if(s.indexOf(x[i].n)>-1){ 
            s=s.replace(new RegExp(s$(x[i].n),"g"),("~"+(iF++)));
            try{
                aF.p(eval(x[i].e))
                
            }catch(e){qErr("Failed on "+(x[i].n+"|"+x[i].e),e)}
        }
    }
    return isNum((sRet=s.format(aF)))?parseInt(sRet):sRet
}
 
function qGetTimeWithMS(){return (new QDate()).format("yyyy-MM-dd HH:mm:ss.S")}
function isValidDate(s) {return (new QDate(s)).isValid?true:false}
function qDateDiff(sD1, sD2, sType){
    // Calculates difference between two dates. sType must be one of y,m,d
    // Does not handle time!
    var
        d1=new QDate(sD1),iY1,iM1,iD1,iDIM1,
        d2=new QDate(sD2),iY2,iM2,iD2,iDIM2
    try {
        sType=sType.toLowerCase()
        if(sType=="d"){ return ( ( d2.ms - d1.ms ) / (1000*60*60*24) ) }
        iY1=d1.format("yyyy");iM1=d1.format("M");iD1=d1.format("d");iDIM1=d1.getDaysInMonth()
        iY2=d2.format("yyyy");iM2=d2.format("M");iD2=d2.format("d");iDIM2=d2.getDaysInMonth()
        if(sType=="y"){
            return ( iY2 + ( iM2 / 12 ) + ( ( iD2/iDIM2 ) / 12 ) ) - ( iY1 + ( iM1 / 12 ) + ( ( iD1 / iDIM1 ) / 12 ) ) 
        }else if(sType=="m"){
            var iRet=( ( iY2*12 ) + iM2 + ( iD2/iDIM2 ) ) - ( ( iY1*12 ) + iM1 + ( iD1/iDIM1 ) ),sNum=String(iRet),iInd=sNum.indexOf(".99"),iDec
            return iInd==-1?iRet:Number(iRet).toFixed(0)
        }else
            qErr("qDateDiff error: Invalid diff type in sType: `"+sType+"`...  Expected [y,m,d]" )
    } catch(e) {debug(e)
        if(!d1.isValid){qErr("invalid date passed to sD1: "+sD1)}
        if(!d2.isValid){qErr("invalid date passed to sD2: "+sD2)}
        throw e
    }
}
/* END DATE */




/* EVENTS */
function getEvent(e){
    if(isEvent(e)||!is.ie){return e}; 
    e=_w.event;
    if(e==null){return null;}
    e.target=e.srcElement; 
    e.timeStamp=s$(new Date()); 
    return e
}
// Gets Source Element from Event
function getEvnSource(e){
    var oS
    if(!isEvent(e)){return null;}
    oS=e.source||e.qSource
    return oS?oS:null
}
/* usage:
   . assignEventListiner(oE, "click", function (e){e=getEvent(e);var oS=this;...//
   .. where: e=Event, oS - Source Event Element
 */

function assignEventListener(oE,sEv,fH){try{
    var oEBase=oE,sTrc="", sTrcb=""
  sTrc="Getting Element"
    if(isElem(oE))oE=agetElem(oE)
    if(is.ie){
//      pc("Building Statement")
        var sEval="oE.on"+sEv+"=fH"
//      pc("Evaluating Statement")
        try{eval(sEval)}catch(x){
//          pc("Eval Error being sent. msg="+x.message)
            var d,b
            qErr(
                 "Assign handler eval error."+
                +"\n\n PLEASE REPORT THIS ERROR TO DEV TEAM!!!"
                +"\n[ Debug Info ]"
                +"\n sEval: "+sEval
                +"\n oEBase: "+oEBase
                +"\n oE: "+oE
                +"\n isDef(oE): "+isDef(oE)
                +"\n isElem(oE): "+isElem(oE)
                +"\n oE.name: "+oE.name
                +"\n oE.id: "+oE.id
                +"\n oE.tagName: "+oE.tagName
                +"\n oE is window: "+(oE==_w)
                +"\n oE is document: "+((d=_w.document)?(oE==d):"no document yet")
                +"\n oE is body: "+(d&&(b=d.body)?(oE==b):"no body yet")
            ,x)
        }
    }else{
        oE.addEventListener(sEv,fH,true)
    }
}catch(e){qErr(e)}}
_AEL = assignEventListener

function PseudoEvent(j){
    var t=this,v
    if(!isJson(j))j={}
    t.isPseudoEvent=true
    t.type=(v=j.types)?v:""
    t.target=(v=j.target)?v:""
    t.keyCode=(v=j.keyCode)?v:""
    t.qSource=(v=j.target)?v:""
}
    


/* NUMBER */
function nToFixed(n,d) { 
    if(isNaN(d)){d=0}
    if(!is.ie){// Fix rounding issue in Moz
        var sN=s$(n),iInd=sN.indexOf('.')
        if (iInd > -1){ if(sN.length-(iInd+1)>d){ return Number(sN+"1").toFixed(d) } } 
    }
    return Number(n).toFixed(d)
}
function nRand(iDig) {// Returns random num to iDig Digits to max of 16
    var sR=s$(Math.random()).replace(/\./g,""),iL=sR.length
    if(iL==16){ sR+="0" }
    if(!isNum(iDig)||iDig<1||iDig>16){iDig=16}
    return sR.substring(1,iDig)
}


/* GENERAL */
function winWidth(){return is.ie?_d.body.clientWidth:_w.innerWidth}
function winHeight(){return is.ie?_d.body.clientHeight:_w.innerHeight}
function winQuickRefresh(){var o=new ParsedURI();o.updateRand();_w.location.href=o}
function elemHeight(obj) { return obj.offsetHeight }
function elemWidth(obj) { return obj.offsetWidth}
function winTest(w){
	var x
    try{
    	
//debug(
//   +"\n w = "+w
//   +"\n w.location = "+w.location
//   +"\n w.location.href = "+w.location.href
//   +"\n w.document.body = "+w.document.body
//   +"\n w.document.body.name = "+_w.document.body.name
//)

		x=w.location
		x=x.href
        x=w.document
        x=x.body
        x=x.name
    }catch(
        e
    ){return false}; return w 
}

/* CUSTOM ERRORS / ERROR METHODS
    Usage:
    - Call init method of Error Class
    -- this.name = <ERR_CLS_CONST>;
    - Use err.isInstanceOf(<ERR_CLS_CONST>) to detect if instance of class
    - Where:
    -- <ERR_CLS_CONST> = Global String Constant Unique for Each Custom Error Class
*/
_EP=Error.prototype;
ERRCLS_qRpcError="qRpcError"
qRpcError = function qRpcError_ctor(iCode,sMsg,sJavaStack){
    var t=this
    t.name=ERRCLS_qRpcError
    try {
        t.code=agetParam_int("arg 0 (iCode)", arguments, "0", true)
        t.message=agetParam("arg 1 (sMsg)", arguments, "1", false)
        t.javaStack=agetParam("arg 2 (sJavaStack)", arguments, "2", false)   
        if(!is.ie){t.stack=(new Error()).stack}
    }catch(x){
        qCoreErr("!!!qRpcError ctor failed!!!",x,{varDump:{args: q$.dumpArgs()}})   
    }
}
qRpcError.prototype = new Error();
qRpcError.prototype.toString = function qrpcerr_toString(){
    var t=this,s,v
    s=isDef(v=t.message)?v:("message is undefined")
    v=t.javaStack; if(v)s+="\nJava Stack:\n"+s$.pad(v,". ")
    s+="\nJS Stack:\n"+s$.pad(getStackTrace(t),". ")
    v=t.code; if(v)s+="\nErr Code:\n"+s$.pad(v,". ")
    return s
}
_EP.isInstanceOf = function err_isInstanceOf(sErrClassName){
    var t=this,sN=t.getClassName()
    return (sN == sErrClassName)
}
_EP.getClassName = function err_getClassName(){
    return this.name
}
/* Assumes that Error implements toString() which includes more details than .message */
_EP.getMessage = function err_getMessage(){
    var t=this,s=t.message
    return isDef(s)?s:q$.NULL
}
_EP.getErrorDetails = function err_getErrorDetails(){
    var t=this,s=t.toString(),s2=t.getMessage(),i
    if(!isStr(s))return q$.NULL
    i=s.indexOf(s2)
    if(!isStr(s2)||i==-1)return s
    s=s.substring(s2.length).trim()
    return s
}
/* Designed for use by Core Errors Only */
_EP.dump = function err_dump(){
    var t=this,s,v
    s=isDef(v=t.message)?v:("message is undefined")
    v=t.getErrorDetails(); if(v)s+="Details:\n"+s$.pad(v,". ")
    try {
        v=getStackTrace(this)
    }catch(w){
        v+="Could not capture Stack Trace because of error '"+w.message+"'"+(is.ie?"":"(RAW)\n"+t.stack)  
    }
    s+="Stack:\n"+s$.pad(v,". ")
    return s
}


/* Global Error Handler */
function Window_error(sMsg,sURI,iLine){//alert("Window_error - called: iLine="+iLine+"|"+arguments.length)
pc("CALLED")

//alert("!Window_error! sMsg = `" +sMsg+"`, iLine = `" +iLine+"`")

    
//return
  var bDoConf=true,iErrRnd=nRand(4)

  // ERROR TRAPS
    if(!is.ie&&sMsg=="Error loading script"&&parseInt(iLine)==1){ return false }
  // END ERROR TRAPS

    try {

        if(_w._DisableAllErrors){return true}

        var
             n=navigator,err=q$._LastErr,d,bQE=isQErr(err),o
            ,dd,ddOther,v,caller=arguments.callee.caller, bUseQE=false
            ,sErr,bMsgIsQErr=(s$(sMsg).indexOf(q$.TO_STR_TITLE)>-1)?true:false
            ,sOther,stack,bSkipCoreErr
        ;   
//pc(
//    "!!!Window_error!!!"
//   +"\n err = "+err
//   +"\n sMsg = "+sMsg
//   +"\n sURI = "+sURI
//   +"\n iLine = "+iLine
//   +"\n err.message = "+(isError(err)?err.message:"(n/a)")
//   +"\n bQE = "+bQE
//   +"\n isError(err) = "+isError(err)
//   +"\n isQErr(err) = "+isQErr(err)
//   +"\n CALL STACK: "+s$.pad((new Error()).stack, ". ")
//)
        if(bQE && err == q$._LastErr){
        	err[q$.MK_errorHandled]=true
        	q$.clearLastError(true)
        }
//alert("!Window_error! bMsgIsQErr = `" +bMsgIsQErr+"`, bQE = `"+bQE+"`")

        if(bQE){
            bUseQE=true
            dd=debugDump(err,{verbose:true})
//pc(
//    "!!!Window_error!!!"
//   +"\n dd.MESSAGE = "+dd.getSect(dd.MESSAGE)
//)
        }else{
            dd=new qDD()
            if(is.ie){
                stack=getStackTrace("",true)
                dd.setSect(dd.STACK_ARRAY, stack)
                dd.append(dd.STACK, q$.compileStack(stack))
            } else
                dd.append(dd.STACK, "(not available)")
                
            dd.append(dd.MESSAGE, s$.pad(sMsg+((!is.ie&&isUndef(caller))?"\n(See JavaScript Console for more error detail)":""),". "))
            if(err){
            	q$.parseErr(err)
                dd.rootCause=err
            }
        }

//pc(
//    "!!!Window_error!!!"
//   +"\n dd.STACK:\n"+dd.getSect(dd.STACK)
//)
        __ai("Err Line", iLine==0?undefined:iLine);
        if(is.ie)__ai("Caller", (funcName(caller)||undefined));
        if(!bUseQE) __ai("Date", (new QDate()).format("yyyy-MM-dd HH:mm:ss"));
        __ai("Browser", navigator.userAgent);
        if(is.ie)__ai("Browser Minor Ver", navigator.appMinorVersion);
        if(is.ie)__ai("IE Doc Charset", document.charset);
        __ai("URI", location.href);
        try{v=_d.getElementsByTagName("title")[0].innerHTML}catch(e){}; __ai("Page Title", v);
        if(!bUseQE&&isDef(sOther))__ai("Related Error? ", s$.pad(sOther));
        
      // Test for qClient
        if(_w._qclient&&isFunc(_w._qclient.priv_errorHandler)){
//alert(
//    "!!! dd.rootCause = "+dd.rootCause
//   +"\n\n Stack: "+s$.pad((new Error()).stack, ". ")
//)
            if(_w._qclient.priv_errorHandler(dd)){
                return true
            }
        }
//pc(
//    "!!!Window_error!!!"
//   +"\n bSkipCoreErr = "+bSkipCoreErr
//   +"\n dd.STACK:\n"+s$.pad(dd.getSect(dd.STACK))
//)
        var bDoConf=true

        if(!bSkipCoreErr){
            sErr="JAVASCRIPT EXCEPTION\n\n"+dd.toString(QOpt({sectType: "alert", spaceSection: true, verbose: true}))+"\n\nEND\n";
            try {
                var iTop, sElemID="divJSE"+iErrRnd,oEl
                try{iTop=_d.body.scrollTop}catch(xx){iTop=0}
                var sDiv=
                "<div id="+sElemID+" title='JavaScript Error: See JS Console to copy message' style='font: bold 12px arial; width: 175px; background: red; color: white; border: 1px solid #777; position: absolute; top:"+iTop+"; right: 0; padding: 0 3 1 3; cursor: help;text-decoration: blink; z-index: 10000; overflow: auto'>"+
                    "<div style='white-space: nowrap; height: 17px'>"+
                        "<span style='text-align: left'>&nbsp;<img src='"+_w.imagePath+"iconErrorSmall.gif' height=15 style='position: absolute; top: 1px'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript Error <b style='font-size: 9px'>(#"+iErrRnd+")</b></span>"+
                        "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b  id="+sElemID+"_pm onclick='ErrorPopup_PlusMinus_click(this, event,\""+sElemID+"\")' style='width: 10px; width: 10px; text-align: center; position:absolute; top:-4; right:3; font: bold 15px arial black'>+</b>"+
                    "</div>"+
                    "<div id="+sElemID+"_msg style='overflow: auto; display:none; background: navy; padding: 3 3 3 3; border: 3px solid #aaa; font-size: 11px; color: #eee'></div>"+
                "</div>"
                for(var i=0;i<20;i++)
                setTimeout("try{getElem(\""+sElemID+"\").style.top=_d.body.scrollTop}catch(e){}",1000*i)
                if(_d.body) { _d.body.innerHTML+=sDiv } else { dw(sDiv) }
                oEl=getElem(sElemID); oEl.errMessage=sErr;
                if(_w.bAutoExpandErrors){oEl=getElem(sElemID+"_pm"); oEl.onclick(oEl,{isPseudoEvent:true,target:oEl},sElemID)}
                bDoConf=false
                if(_w.bDebug)
                    ErrorPopup_PlusMinus_click(getElem(sElemID+"_pm"), undefined, sElemID)
            }catch(xxx){ 
                alert("Window_error - Internal Error: "+xxx.message+(is.ie?"":"\nstack:\n"+xxx.stack))
            }
            if(bDoConf){
                var bConf=confirm(!is.ie?sErr.replace(/ /g,"\xA0"):sErr)
                if(_w.bDebug&&!bConf)_CL.debugDump()
                if(!_w.bDebug&&bConf)_DisableAllErrors=true
            }
        }
       
       
    }catch(e2){

        sTmp="CORE ERROR CAUGHT:\n"+s$.pad(e2.dump())
        try { pc(sTmp) }catch(xx){}
        alert(sTmp);
        
        window.onerror=""
        qCoreErr("Window_Error handler Failed",e2,{varDump:{args: q$.dumpArgs()}});
    }
        
    if(!is.ie&&!bDoConf && sErr){
        _DisableAllErrors=true
        throw new Error("Internal Error Caught. id=`"+iErrRnd+"`\n\n"+sErr)  
        _DisableAllErrors=false
    }
    
    function __ai(sK,sV,bShowIfNull){if(!bShowIfNull&&isUndef(sV))return; dd.append(dd.INFO, [sK,isDef(sV)?sV:"(null)"])}
}

function ErrorPopup_PlusMinus_click(o,e,sElemID){try{//debug("called")
    var divErrPopup=getElem(sElemID),oMsgFrame=o.parentNode.nextSibling,bIsPlus=(o.innerHTML.trim()=="+")
    oMsgFrame.style.display=(bIsPlus?"":"none")
    oMsgFrame.innerHTML=s$(divErrPopup.errMessage).convSpecialCharsToHtml().replace(/\n/g,"<br>")
    o.innerHTML=(bIsPlus?"-":"+")
    divErrPopup.style.width=(bIsPlus?"600":"175")+"px"
    divErrPopup.style.textDecoration=""
}catch(x){debug(x)}}// Do not throw debugErr!
    
// Assign Global Error Handler
_w.onerror = Window_error
    
function __finalizeInit(){
    
    try {
      _w.oURI=new ParsedURI()
      _w.serverPath=oURI.getURL()
    }catch(e){
       try{window.location.href}catch(e){ alert("window.location.href error - Check that this JS is not specified before JS declarations") }
    }
  
}__finalizeInit()

/* Global wrapper for _qclient.qcGate() */
function _qcGate(e){ return (_w._qclient && _qclient.qcGate(e))?true:false}

/* qDB1 */
qObjAppend(q$, {
    MK_isDb1Table: "isDb1Table"
   ,MK_isDb1Rec: "isDb1Rec"
})
function arrToMapList(aTbl, j){
	var
		aTbl, aCoreRows, iKeyRow
	   ,aRet, jR = {},aRec, aKeyRec, sKey, v
	   ,bClean,bIndx,sIndxCol,sIndxPfx,sIndKey
	;j=j?j:{}
	iKeyRow = agetParam_int("j (json args)", j, "keyRow", false);
	aCoreRows = agetParam_arr("j (json args)", j, "coreRows", false)
	bClean = agetParam_bool("j (json args)", j, "clean", false)
	bIndx = agetParam_bool("j (json args)", j, "index", false)
	if(bIndx){
		sIndxPfx = agetParam("j (json args)", j, "indexPfx", false)
		sIndxCol = agetParam("j (json args)", j, "indexCol", false)
	}
	if(iKeyRow == -1){ iKeyRow = 0; aCoreRows=["keyRow"] }
		
  // Load Key Column
  	aKeyRec = aTbl[iKeyRow]
  // Start Building Return
  	aRet = []
	aRet[q$.MK_fieldKeys]=aKeyRec
	aRet[q$.MK_isDb1Table]=true
  	for(var i=aCoreRows.length;i<aTbl.length;i++){aRec = aTbl[i]
  		jR={isDb1Rec: true, jsParent: aRet}
		for(var j=0;j<aKeyRec.length;j++){
			sKey = aKeyRec[j]
			v=aRec[j]
			jR[sKey] = (bClean && isStr(v))?v.convSpecialCharsToNorm():v
		}
		aRet.p(jR)
		if(bIndx){
			sIndKey = jR[sIndxCol]
			aRet[sIndxPfx+sIndKey]=jR
		}
		
	}
	return aRet
}
function arrToMap(aNV, j){
	var k, v, jR={},bClean;j=j?j:{}
	bClean = agetParam_bool("j (json args)", j, "clean", false)
  	for(var i=0;i<aNV.length;i++){
  		k = aNV[i++]
  		jR[k] = (bClean && isStr(v=aNV[i]))?v.convSpecialCharsToNorm():v
	}
	return jR
}
/* end qDB1 */